Android5.x:RecycleView(四):item動畫

給item添加動畫有3種方法:
- 在onBindViewHolder()裏面中給item設置動畫
- 自定義ItemAnimator,比如DefaultItemAnimator
- 自定義佈局動畫(LayoutAnimation)

LayoutAnimation

參考:RecyclerView 與 LayoutAnimation 實現的進入動畫(一 ): List

這裏寫圖片描述

效果圖

這裏寫圖片描述

使用方式

我們採用第三種,有2種使用方式,一種是java代碼,另一種是xml中引用動畫資源文件。

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

XML中引用:

<android.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

<?xml version="1.0" encoding="utf-8"?>
<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:

<?xml version="1.0" encoding="utf-8"?>
<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

對比圖如下:(來自上面參考博文),實際操作沒出來效果
這裏寫圖片描述

我的效果
這裏寫圖片描述 這裏寫圖片描述

爲什麼重寫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:屬性都好理解。

<?xml version="1.0" encoding="utf-8"?>
<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%"/>
發佈了303 篇原創文章 · 獲贊 77 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章