Animate RecyclerView when scrolling

前端 未结 3 1409
夕颜
夕颜 2020-12-24 08:02

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

I took a look at DefaultItemAnimator and RecyclerView.ItemAnimator

相关标签:
3条回答
  • 2020-12-24 08:25

    I did it this way. Might help someone. I don't know whether it's the best way to do it but works fine for me.

    UPDATE: To fix fast scrolling behaviour, override onViewDetachedFromWindow method of the adapter and call clearAnimation on the animated view (in this case, holder.itemView.clearAnimation() ).

    up_from_bottom.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:anim/decelerate_interpolator">
    <translate
        android:fromXDelta="0%" android:toXDelta="0%"
        android:fromYDelta="100%" android:toYDelta="0%"
        android:duration="400" />
    </set>
    

    down_from_top.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:anim/decelerate_interpolator">
    <translate
        android:fromXDelta="0%" android:toXDelta="0%"
        android:fromYDelta="-100%" android:toYDelta="0%"
        android:duration="400" />
    </set>
    

    And finally put this code in onBindViewHolder of recyclerView. Create a field called lastPosition and initialize it to -1.

    Animation animation = AnimationUtils.loadAnimation(context,
                (position > lastPosition) ? R.anim.up_from_bottom
                        : R.anim.down_from_top);
        holder.itemView.startAnimation(animation);
        lastPosition = position;
    
    0 讨论(0)
  • 2020-12-24 08:33

    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();
        }
    });
    
    0 讨论(0)
  • 2020-12-24 08:34

    The good solution is to animate holder in adapter in onBindViewHolder method. Snippet taken from Material Test project Slidenerd:

    @Override 
    public void onBindViewHolder(ViewHolderBoxOffice holder, int position) {
        Movie currentMovie = mListMovies.get(position);
        //one or more fields of the Movie object may be null since they are fetched from the web 
        holder.movieTitle.setText(currentMovie.getTitle());
    
    
        //retrieved date may be null 
        Date movieReleaseDate = currentMovie.getReleaseDateTheater();
        if (movieReleaseDate != null) {
            String formattedDate = mFormatter.format(movieReleaseDate);
            holder.movieReleaseDate.setText(formattedDate);
        } else { 
            holder.movieReleaseDate.setText(Constants.NA);
        } 
    
    
        int audienceScore = currentMovie.getAudienceScore();
        if (audienceScore == -1) {
            holder.movieAudienceScore.setRating(0.0F);
            holder.movieAudienceScore.setAlpha(0.5F);
        } else { 
            holder.movieAudienceScore.setRating(audienceScore / 20.0F);
            holder.movieAudienceScore.setAlpha(1.0F);
        } 
    
    
        if (position > mPreviousPosition) {
            AnimationUtils.animateSunblind(holder, true);         
        } else { 
            AnimationUtils.animateSunblind(holder, false);
    
        } 
        mPreviousPosition = position;
    

    here is a link

    0 讨论(0)
提交回复
热议问题