tl;dr How to wait until the true scrolling is done after calling scrollToPosition()? What I mean by true scrolling is that (1) the RecyclerView
has finished the scrolling and (2) it has bound all the ViewHolder
s for the set position of scroll.
Description:
I am trying to fix some transition animation for recycler view and I'm having a hard time achieving it.
The app is consistent of a RecyclerView
in one of the activities and a ViewPager
that acts as a "detail view" when users click on an item in the RecyclerView
.
The forward navigation from RecyclerView
to ViewPager
works perfectly fine but the problem is, the backward navigation doesn't work. Please note that the user may navigate using the ViewPager
in the detail view and when they re-enter the activity with RecyclerView
, the position of the item may be different from the original case, meaning the RecyclerView
needs to scoll first to the item and then resume the transition animation.
The reason I can't make it to work is because I resume the animation before the RecyclerView
has properly scolled and bound the underlying ViewHolder
s but I don't know how to wait for the scrolling to truly finish and then resume the shared element transitions.
What I do in my code (on the Reenter
code) is this:
if (isReentering) {
// postpone the animation here
ActivityCompat.postponeEnterTransition(getActivity());
scollIndex = ... // determine the correct item position
layoutManager.scrollToPosition(scrollIndex);
final RecyclerView recyclerView = getRecyclerView();
new Handler().post(new Runnable() {
@Override
public void run() {
recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
recyclerView.requestLayout();
ActivityCompat.startPostponedEnterTransition(getActivity());
return true;
}
});
}
});
}
I also set the transition name in my Adapter
as such:
@Override
public void onBindViewHolder(TViewHolder holder, int position) {
....
holder.setTransitionName(_data.get(position).getContentId().toString());
}
The transition name is the UUID of the item, set in the underlying View
. Both the ViewPager
and the RecyclerView
set this correctly.
The scrollIndex
is correct and the RecyclerView
does scroll to it but here's the catch: The scrolling and binding only takes effect after I've already started the postponed enter transition in my code (by calling ActivityCompat.startPostponedEnterTransition(getActivity());
) which causes weird transition animations.
What I would like to happen is to somehow wait until the scrolling and the ViewHolder
binding is finished before calling startPostponedEnterTransition
so my question is, how can I find out when the scrolling has finished and all the ViewHolder
s are bound so that I can call this?
Many thanks in advance,