RecyclerView<第七篇>:添加入場動畫

隨着RecycleView的普及運用,它越來越多的逼格展示在我們面前,下面我來爲RecycleView添加入場動畫。

Android動畫<第一篇>:視圖動畫這篇博客上提到過佈局動畫(LayoutAnimation),這個動畫同樣可以運用在RecycleView,使RecycleView的Item實現逼格的入場動畫。

效果如下:

核心思想是:給RecycleView添加一個佈局動畫

該動畫的代碼如下:

anim_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/animation_popup_enter"
    android:animationOrder="normal"
    android:delay="0.2"/>

有關layoutAnimation標籤下的屬性的解釋:

android:delay 表示動畫播放的延時,既可以是百分比,也可以是 float 小數。
android:animationOrder 表示動畫的播放順序,有三個取值 normal(順序)、reverse(反序)、random(隨機)。
android:animation 指向了子控件所要播放的動畫。

animation_popup_enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="2000"
        android:fromXDelta="-100%"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="0"/>
    <alpha
        android:duration="2000"
        android:fromAlpha="0"
        android:toAlpha="1"
        />
</set>

那麼,如果是GridLayout的佈局呢?

我們只需要將

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(RecycleViewActivity.this);
    recycleview.setLayoutManager(linearLayoutManager);

改成

    GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 4);
    recycleview.setLayoutManager(gridLayoutManager);

就可以轉成GridLayout佈局,那麼在這種佈局下,使用和上面一樣的入場動畫效果如下:

如圖,展示一個從左到右入場的動畫,該動畫每個Item的動畫時間是2s,layoutAnimation中設置的延遲時間delay是0.2,假設Item的動畫時間用animTime表示,這裏的延遲時間比例是0.2,延遲時間的計算方式如下:

delay = animTime * 0.2 = 2000 * 0.2 = 400ms

layoutAnimation中delay屬性值爲0.2,也可以設置成20%,如下:

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/animation_popup_enter"
    android:animationOrder="normal"
    android:delay="20%"/>

說到這裏,我們會發現一個問題,Item是一個一個展示的,這樣花費了大量的時間,有人說,可以減小動畫時間和動畫的延遲時間,那麼,行,我來縮短動畫時間:(將2000ms改成200ms)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromXDelta="-100%"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="0"/>
    <alpha
        android:duration="200"
        android:fromAlpha="0"
        android:toAlpha="1"
        />
</set>


<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/animation_popup_enter"
    android:animationOrder="normal"
    android:delay="0.2"/>

動畫效果如下:

除了layoutAnimation之外,官方還提供了gridLayoutAnimation動畫,使用gridLayoutAnimation動畫必須自定義RecyclerView,否則崩潰。

自定義RecyclerView如下:

public class GridRecyclerView extends RecyclerView {
    public GridRecyclerView(@NonNull Context context) {
        super(context);
    }

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

    public GridRecyclerView(@NonNull 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);
        }
    }
}

它同樣需要在佈局上添加layoutAnimation:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cccccc">


    <com.zyc.hezuo.animationdemo.GridRecyclerView
        android:id="@+id/recycleview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layoutAnimation="@anim/anim_layout"/>
</RelativeLayout>

anim_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/animation_popup_enter"
    android:animationOrder="normal"
    android:rowDelay="15%"
    android:columnDelay="15%"
    android:direction="top_to_bottom"/>

有關gridLayoutAnimation 標籤下的屬性的解釋:

android:rowDelay表示動畫播放的行延時,既可以是百分比,也可以是 float 小數。
android:columnDelay表示動畫播放的列延時,既可以是百分比,也可以是 float 小數。
android:animationOrder 表示動畫的播放順序,有三個取值 normal(順序)、reverse(反序)、random(隨機)。
android:animation 指向了子控件所要播放的動畫。
android:direction表示Item展示的方向,它有四個取值top_to_bottom(從上往下)、left_to_right(從左往右)、right_to_left(從右往左)、bottom_to_top(從下往上)

animation_popup_enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/anticipate_overshoot">
    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:fromYDelta="100%"
        android:toXDelta="0"
        android:toYDelta="0"/>
    <alpha
        android:duration="500"
        android:fromAlpha="0"
        android:toAlpha="1"
        />
</set>

其效果如下:

這裏稍微關注一下direction屬性,從上圖效果可以看出direction的屬性是top_to_bottom|left_to_right,其餘兩個取值我想沒必要多說了。

[本章完...]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章