-
Notifications
You must be signed in to change notification settings - Fork 386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there any sample code about cross activities from recyclerview to viewpager? #91
Comments
It's really hard to help if you don't provide your code. Please share related code pieces and describe your problems with it. It seems like you just need to hide everything on last animation step (isLeaving && pos == 0) |
I have the same question, need sample too |
I try to write a simple demo here. The problem is when ToActivity exit it will have a flash. I tried debug and slow down animation but don't see any thing so I suspect the original image showed after ToActivity disappear so it will see a empty place and show ImageView immediately after that. The result is a flash.
<CoordinatorLayout>
<AppBarLayout>
<Toolbar />
</AppBarLayout>
<RecyclerView android:id="@+id/recycler_view" />
</CoordinatorLayout>
class FromActivity extend AppCompatActivity {
private mRecyclerView: RecyclerView;
private mAdapter: PhotoAdapter;
public override void onCreate(/*...*/) {
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new GridLayoutManager(/*...*/));
mAdapter = new PhotoAdapter();
mRecyclerView.setAdapter(mAdapter);
}
@Subscribe
void onImageShowEvent(ImageShowEvent event) {
if (event.adapterPosition < photo.getSize()) {
StatusViewHolder holder = (StatusViewHolder)mRecyclerView.findViewHolderForAdapterPosition(event.adapterPosition)
holder.statusImage.setVisibility(event.show ? View.VISIBLE : View.INVISIBLE)
}
}
}
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/photo_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<View
android:id="@+id/photo_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"/>
<android.support.v4.view.ViewPager
android:id="@+id/photo_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
</android.support.v4.view.ViewPager>
<FrameLayout
android:id="@+id/status_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:fitsSystemWindows="true"
android:background="#80000000">
<TextView
android:id="@+id/photo_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:textSize="10sp"
android:textColor="?android:attr/textColorPrimaryInverse"/>
</FrameLayout>
</FrameLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.alexvasilkov.gestures.views.GestureImageView
android:id="@+id/photo_full_image"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
class PhotoDetailPagerAdapter(val viewPager: ViewPager,
val photoList: List<Status>,
val photoInfos: List<ImageInfo>,
val thumbnailUri: Uri?,
val actionDelegate: ActionDelegate) : RecyclePagerAdapter<PhotoDetailPagerAdapter.ViewHolder>() {
// PLEASE ignore the different constructor parameters in FromActivity.java
private var firstView = true
private val context = viewPager.context
var activated = true
set(value) {
if (field != value) {
field = value
notifyDataSetChanged()
}
}
override fun onCreateViewHolder(container: ViewGroup): ViewHolder {
val holder = ViewHolder(container)
holder.image.controller.settings
.setMaxZoom(10f)
.setDoubleTapZoom(3f)
.setDoubleTapEnabled(true)
.setFitMethod(Settings.Fit.INSIDE)
.setZoomEnabled(true)
.setExitEnabled(true)
.setFillViewport(true)
.setGravity(Gravity.CENTER)
.setPanEnabled(true)
holder.image.controller.setLongPressEnabled(true)
holder.image.controller.enableScrollInViewPager(viewPager)
return holder
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val photoInfo = photoInfos[position]
loadImage(photoInfo, holder.image)
holder.image.controller.setOnGesturesListener(object : GestureController.OnGestureListener {
override fun onSingleTapUp(event: MotionEvent): Boolean = false
override fun onDown(event: MotionEvent) {
}
override fun onDoubleTap(event: MotionEvent): Boolean = false
override fun onUpOrCancel(event: MotionEvent) {}
override fun onLongPress(event: MotionEvent) {
actionDelegate.onLongClick(holder, photoList[position], photoInfo)
}
override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
actionDelegate.onClick()
return true
}
})
}
override fun onRecycleViewHolder(holder: ViewHolder) {
super.onRecycleViewHolder(holder)
Glide.clear(holder.image)
holder.image.setImageDrawable(null)
}
override fun getCount(): Int = if (!activated) 0 else photoList.size
private fun loadImage(info: ImageInfo, imageView: GestureImageView) {
if (firstView && thumbnailUri != null) {
Image.loadImage(context, thumbnailUri, imageView, false)
}
firstView = false
if (info.height / info.width > Image.LARGE_SCREEN_RATIO) {
imageView.controller.settings
.setFitMethod(Settings.Fit.HORIZONTAL).gravity = Gravity.TOP
} else {
imageView.controller.settings
.setFitMethod(Settings.Fit.INSIDE).gravity = Gravity.CENTER
}
val gif = info.imageUri?.let { Image.getMimeType(info.imageUri) == "image/gif" } ?: false
when (info.cacheState) {
ImageInfo.CACHE_NONE,
ImageInfo.CACHE_THUMBNAIL -> {
val large = (info.height / info.width > Image.LARGE_SCREEN_RATIO)
val param = Image.getLoadParameter(imageView, info.imageUri!!, large, false)
Image.loadImage(context, Uri.parse(info.imageUri.toString() + param), imageView, false, false)
}
ImageInfo.CACHE_LARGE -> {
val param = Image.getLoadParameter(imageView, info.imageUri!!, false, true, 576)
Image.loadImage(context, Uri.parse(info.imageUri.toString() + param), imageView, false, gif)
}
ImageInfo.CACHE_ORIGIN -> {
Image.loadImage(context, info.imageUri!!, imageView, false, gif)
}
}
}
override fun destroyItem(container: ViewGroup?, position: Int, `object`: Any?) {
super.destroyItem(container, position, `object`)
}
inner class ViewHolder(parent: ViewGroup) : RecyclePagerAdapter.ViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_photo_full, parent, false)) {
val image: GestureImageView by lazy { itemView.findViewById<GestureImageView>(R.id.photo_full_image) }
}
interface ActionDelegate {
fun onClick()
fun onLongClick(holder: ViewHolder, status: Status, item: ImageInfo): Boolean
}
}
class PhotoDetailActivity : AppCompatActivity,
ViewPositionAnimator.PositionUpdateListener,
PhotoDetailPagerAdapter.ActionDelegate {
private val viewPager: ViewPager by lazy { findViewById<ViewPager>(R.id.photo_pager) }
private val pagerAdapter by lazy { PhotoDetailPagerAdapter(viewPager, photoList, photoInfos, thumbnailUri, this) }
private val pagerTracker: SimpleTracker by lazy {
object : SimpleTracker() {
override fun getViewAt(position: Int): View? = pagerAdapter.getViewHolder(position)?.image
}
}
private val animator: ViewsTransitionAnimator<Int> by lazy {
GestureTransitions.from(fromRecyclerView?.get()!!, fromTracker!!).into(viewPager, pagerTracker)
}
private val statusText by lazy { findViewById<TextView>(R.id.photo_status) }
private val statusLayout by lazy { findViewById<FrameLayout>(R.id.status_layout) }
private val background: View by lazy { findViewById<View>(R.id.photo_background) }
private var position = 0
private var hideOrigImage = false
private var fromPosition: Int = -1
private var currentPosition: Int = 0
override val isCommonTheme: Boolean
get() = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_photo_detail)
if (savedInstanceState != null) {
position = savedInstanceState.getInt("POSITION", 0)
}
fromPosition = intent.getIntExtra(EXTRA_POSITION, -1)
animator.enter(position, savedInstanceState == null)
initPager()
initAnimator()
}
private fun initPager() {
viewPager.adapter = pagerAdapter
pagerAdapter.activated = true
viewPager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
override fun onPageSelected(position: Int) {
onPhotoInPagerSelected(position)
}
})
onPhotoInPagerSelected(0)
}
private fun initAnimator() {
animator.addPositionUpdateListener(this)
}
private fun onPhotoInPagerSelected(position: Int) {
currentPosition = position
val status = photoList[position]
val html = String.cleanTag(status.text)
statusText.text = html
// HERE: I tried to hide origin ImageView in another activity like your sample but failed.
// val image = pagerAdapter.getViewHolder(currentPosition).image
// image.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
// override fun onPreDraw(): Boolean {
// if (hideOrigImage) {
// image.viewTreeObserver.removeOnPreDrawListener(this)
// EventBus.getDefault().post(ImageShowEvent(fromPosition, false))
// } else if (image.drawable != null) {
// hideOrigImage = true
// }
// return true
// }
// })
}
override fun onPositionUpdate(position: Float, isLeaving: Boolean) {
background.setVisibility(position != 0f, false)
background.background.alpha = (255 * position).toInt()
statusLayout.setVisibility(position == 1f, false)
statusLayout.background.alpha = (255 * position).toInt()
if (isLeaving && position == 0f) {
EventBus.getDefault().post(ImageShowEvent(fromPosition, true))
val image = pagerAdapter.getViewHolder(currentPosition).image
image.controller.settings.disableBounds()
image.positionAnimator.setState(0f, false, false)
finish()
overridePendingTransition(0, 0)
}
}
override fun onBackPressed() {
if (!animator.isLeaving) {
animator.exit(true)
} else {
animator.exit(false)
finish()
overridePendingTransition(0, 0)
}
}
override fun onClick() {
onBackPressed()
}
override fun onLongClick(holder: PhotoDetailPagerAdapter.ViewHolder, status: Status, item: ImageInfo): Boolean {
val dialog = BottomSheetDialog(this)
dialog.setTitle("Photo Actions")
dialog.show()
return true
}
companion object {
val photoList = mutableListOf<Status>()
val photoInfos = mutableListOf<ImageInfo>()
val sourceRect = mutableListOf<Rect>()
var thumbnailUri: Uri? = null
var fromRecyclerView: WeakReference<RecyclerView>? = null
var fromTracker: SimpleTracker? = null
const val EXTRA_POSITION = "position"
fun reset() {
photoList.clear()
photoInfos.clear()
sourceRect.clear()
}
private fun setPhotoList(statusList: List<Status>, infoList: List<ImageInfo>) {
reset()
if (statusList.any { it.photo == null }) return
photoList.addAll(statusList)
photoInfos.addAll(infoList.map { it.copy(cacheState = ImageInfo.CACHE_ORIGIN) })
thumbnailUri = Uri.parse(infoList[0].imageUri?.toString() + "@200w_1l.jpg")
}
fun open(from: Activity, recyclerView: RecyclerView, tracker: SimpleTracker, position: Int,
statusList: List<Status>, infoList: List<ImageInfo>) {
val intent = Intent(from, PhotoDetailActivity::class.java)
intent.putExtra(EXTRA_POSITION, position)
fromRecyclerView = WeakReference(recyclerView)
fromTracker = tracker
setPhotoList(statusList, infoList)
from.startActivity(intent)
from.overridePendingTransition(0, 0)
}
}
} That all most the entire demo. |
I also expect the answer,thanks |
I have already solved this problem and maybe pack and post it later. The main focus of solution is to write your own |
Can you share the solution with us please? |
@malikthebest Cross-activity from recyclerview to viewpager, this problem solved? |
Recently I try to implement a cross activities demo. But I found that the ToActivity will flash at the moment it finished().
I use a SimpleTracker to generate ViewTransitionAnimator like:
GestureTransitions.from(fromRecyclerView, fromTracker).into(viewPager, pagerTracker)
only different is that fromRecyclerView is in FromActivity and viewPager in ToActivity.
I try to hide/show origin ImageView like your sample code but pageAdapter.getViewHolder always return null. I don't know how to do it.
The text was updated successfully, but these errors were encountered: