Android5.x:RecycleView(四):item动画

给item添加动画有3种方法:
- 在onBindViewHolder()里面中给item设置动画
- 自定义ItemAnimator,比如DefaultItemAnimator
- 自定义布局动画(LayoutAnimation)

LayoutAnimation

参考:RecyclerView 与 LayoutAnimation 实现的进入动画(一 ): List

Android5.x:RecycleView(四):item动画_第1张图片

效果图

Android5.x:RecycleView(四):item动画_第2张图片

使用方式

我们采用第三种,有2种使用方式,一种是java代码,另一种是xml中引用动画资源文件。

LayoutAnimationController loadLayoutAnimation = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_slide_in_right);
recyclerView.setLayoutAnimation(loadLayoutAnimation);

XML中引用:

.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layoutAnimation="@anim/layout_animation_slide_in_bottom"
    android:layout_height="match_parent"/>

详细:

recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
LayoutAnimationController loadLayoutAnimation = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_slide_in_bottom);
recyclerView.setLayoutAnimation(loadLayoutAnimation);
recyclerView.setAdapter(new MyAdapter());

动画资源文件

R.anim.layout_animation_slide_in_bottom


<layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/item_slide_in_bottom"
    android:animationOrder="normal"
    android:delay="15%"
    android:interpolator="@android:anim/overshoot_interpolator"/>

animation:动画资源
animationOrder:动画顺序
delay:上一个item动画执行15%的时候,下一个item的动画才执行

item_slide_in_bottom:


<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="400"
     android:fillAfter="true"
     android:shareInterpolator="true">

    <translate
        android:fromXDelta="0"
        android:fromYDelta="50%p"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:toXDelta="0"
        android:toYDelta="0"/>

    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"/>

set>

数据变化后如何使用布局动画

recyclerView.setLayoutAnimation(loadLayoutAnimation);
recyclerView.getAdapter().notifyDataSetChanged();
//adapter.notifyDataSetChanged();//也可以
recyclerView.scheduleLayoutAnimation();

实际操作发现去掉recyclerView.scheduleLayoutAnimation();也可以:

LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_slide_in_right);
recyclerView.setLayoutAnimation(animation);
adapter.notifyDataSetChanged();

关于刷新数据后item的闪屏问题

加入item有30个,一屏幕只显示10个,我们切换动画时,导致item闪屏。但是如果我们把30条item都滑动一遍后,在切换另外一种LayoutAnimation,那么不会有闪屏。

找到一种解决方案,没有试过。解决RecyclerView notifyItem闪屏问题

recyclerView.getItemAnimator().setChangeDuration(0);
或
((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

GridLayoutAnimation

参考:RecyclerView 与 LayoutAnimation 实现的进入动画(二 ): Grid

其实吧LayoutAnimation放到RecyclerView也是可以的,只不过item是一行一行加载,第一行加载结束,第二行才开始加载,以此类推(每一行最后一个加载delay,第二行才开始加载),我们想要每一行同时加载的效果,就需要重新RecyclerView

对比图如下:(来自上面参考博文),实际操作没出来效果
Android5.x:RecycleView(四):item动画_第3张图片

我的效果
Android5.x:RecycleView(四):item动画_第4张图片 Android5.x:RecycleView(四):item动画_第5张图片

为什么重写RecyclerView

这是因为RecyclerView是使用LayoutManager来布局自己的子view的,它并不知道LayoutManager如何放置子view。因此RecyclerView不知道到底该把AnimationParameter应用到list上还是grid上,而默认是list。为了修复这个问题我们需要一个自定义的RecyclerView,让它知道GridLayoutManager的存在

public class GridRecyclerView extends RecyclerView {

    public GridRecyclerView(Context context) {
        super(context);
    }

    public GridRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public GridRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    @Override
    protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params,
                                                   int index, int count) {
        final LayoutManager layoutManager = getLayoutManager();
        if (getAdapter() != null && layoutManager instanceof GridLayoutManager) {

            GridLayoutAnimationController.AnimationParameters animationParams =
                    (GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;

            if (animationParams == null) {
                // If there are no animation parameters, create new once and attach them to
                // the LayoutParams.
                animationParams = new GridLayoutAnimationController.AnimationParameters();
                params.layoutAnimationParameters = animationParams;
            }

            // Next we are updating the parameters

            // Set the number of items in the RecyclerView and the index of this item
            animationParams.count = count;
            animationParams.index = index;

            // Calculate the number of columns and rows in the grid
            final int columns = ((GridLayoutManager) layoutManager).getSpanCount();
            animationParams.columnsCount = columns;
            animationParams.rowsCount = count / columns;

            // Calculate the column/row position in the grid
            final int invertedIndex = count - 1 - index;
            animationParams.column = columns - 1 - (invertedIndex % columns);
            animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns;

        } else {
            // Proceed as normal if using another type of LayoutManager
            super.attachLayoutAnimationParameters(child, params, index, count);
        }
    }
}

GridLayoutAnimation

同LayoutAnimation一样,既可以在xml中配置,也可以在java中设置。

<com.cqc.recyclyviewitemanimation01.view.GridRecyclerView
    ......
    android:layoutAnimation="@anim/grid_layout_animation"/>

java

LayoutAnimationController loadLayoutAnimation = AnimationUtils.loadLayoutAnimation(context, R.anim.grid_layout_animation);
recyclerView.setLayoutAnimation(loadLayoutAnimation);

grid_layout_animation.xml:属性都好理解。


<gridLayoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/item_slide_in_right"
    android:columnDelay="15%"
    android:direction="left_to_right|top_to_bottom"
    android:directionPriority="row"
    android:rowDelay="15%"/>

你可能感兴趣的:(Android5.x)