Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
386 views
in Technique[技术] by (71.8m points)

android - Animate RecyclerView when scrolling

Is there any way to animate the elements of a RecyclerView when I scroll it?

I took a look at DefaultItemAnimator and RecyclerView.ItemAnimator, but that animations seems to be only called if the dataset has changed, please correct me if I am wrong.

I'm a little confused about RecyclerView.ItemAnimator.animateMove() when is it called? I put some breakpoints into that class but none of them stops my app.

However back to my question how can I animate the RecyclerView? I want that some elements have another opacity, depended on some custom rules.


I did some more reaseach it seems that animation move is exactly that what I'm looking for. That methods are called from dispatchLayout(). Here is the javadoc of that method:

Wrapper around layoutChildren() that handles animating changes caused by layout. Animations work on the assumption that there are five different kinds of items in play:
PERSISTENT: items are visible before and after layout
REMOVED: items were visible before layout and were removed by the app
ADDED: items did not exist before layout and were added by the app
DISAPPEARING: items exist in the data set before/after, but changed from visible to non-visible in the process of layout (they were moved off screen as a side-effect of other changes)
APPEARING: items exist in the data set before/after, but changed from non-visible to visible in the process of layout (they were moved on screen as a side-effect of other changes)
The overall approach figures out what items exist before/after layout and infers one of the five above states for each of the items. Then the animations are set up accordingly:
PERSISTENT views are moved ({@link ItemAnimator#animateMove(ViewHolder, int, int, int, int)}) REMOVED views are removed ({@link ItemAnimator#animateRemove(ViewHolder)})
ADDED views are added ({@link ItemAnimator#animateAdd(ViewHolder)})
DISAPPEARING views are moved off screen
APPEARING views are moved on screen

So far I'm looking for PERSISTENT, DISAPPEARING and APPEARING, but that methods are never called because of this line here:

boolean animateChangesSimple = mItemAnimator != null && mItemsAddedOrRemoved
            && !mItemsChanged;

mItemsAddedOrRemoved is simply always false so none of that callback are ever reached. Any idea how to set set flag correctly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I ended in using an OnScrollListener and animating it in a custom animate() method. In my case that code takes just 2ms so that is no problem for the 60fps.

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(int newState) {
        if(newState == RecyclerView.SCROLL_STATE_IDLE) {
            // special handler to avoid displaying half elements
            scrollToNext();
        }
        animate();
    }

    @Override
    public void onScrolled(int dx, int dy) {
        animate();
    }
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...