日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用LayoutAnimationController为RecyclerView添加动画

發布時間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用LayoutAnimationController为RecyclerView添加动画 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用LayoutAnimationController為RecyclerView添加動畫

@author:莫川

一、前言

為RecyclerView的Item添加動畫有很多中方案,比如通過設置setItemAnimator來實現或者是通過遍歷RecyclerView中的子View,然后分別對子View做動畫。今天介紹一種更加簡單的方式:通過LayoutAnimationController的方式,對RecyclerView的Item做動畫。

二、效果以及源碼

先看效果:首先是對LinearLayoutManager的RecyclerView。

  • 1.使用LayoutAnimationController的8種動畫的播放效果

  • 2.使用GridLayoutAnimationController的8種動畫的播放效果

Github源碼:https://github.com/nuptboyzhb/RecyclerViewAnimation

三、實現方案

(1)LayoutAnimationController

比如實現從依次從左側進入的動畫效果,我們首先需要實現一個Item的動畫效果,然后創建一個LayoutAnimationController對象,并設置每一個item播放動畫的時間延時和item的播放順序。

以從左側進入為例,每個單獨的Item的動畫如下:

  • 1.Item動畫
.../*** 從左側進入,并帶有彈性的動畫** @return*/public static AnimationSet getAnimationSetFromLeft() {AnimationSet animationSet = new AnimationSet(true);TranslateAnimation translateX1 = new TranslateAnimation(RELATIVE_TO_SELF, -1.0f, RELATIVE_TO_SELF, 0.1f,RELATIVE_TO_SELF, 0, RELATIVE_TO_SELF, 0);translateX1.setDuration(300);translateX1.setInterpolator(new DecelerateInterpolator());translateX1.setStartOffset(0);TranslateAnimation translateX2 = new TranslateAnimation(RELATIVE_TO_SELF, 0.1f, RELATIVE_TO_SELF, -0.1f,RELATIVE_TO_SELF, 0, RELATIVE_TO_SELF, 0);translateX2.setStartOffset(300);translateX2.setInterpolator(new DecelerateInterpolator());translateX2.setDuration(50);TranslateAnimation translateX3 = new TranslateAnimation(RELATIVE_TO_SELF, -0.1f, RELATIVE_TO_SELF, 0f,RELATIVE_TO_SELF, 0, RELATIVE_TO_SELF, 0);translateX3.setStartOffset(350);translateX3.setInterpolator(new DecelerateInterpolator());translateX3.setDuration(50);animationSet.addAnimation(translateX1);animationSet.addAnimation(translateX2);animationSet.addAnimation(translateX3);animationSet.setDuration(400);return animationSet;}...

為了讓Item看起來有‘彈性’效果,animationSet添加了三個移動動畫,分別是從左側進入(-100%),移動到右側的10%,然后在從右側(10%)移動到左側(-10%),最后再從(-10%)移動到原本的位置(0%)。這樣就有了移動后的彈性效果。

  • 2.設置LayoutAnimationController的屬性

2.1 設置ViewGroup的子View播放動畫之間的offset。

/*** Sets the delay, as a fraction of the animation duration, by which the children's animations are offset.*/ void setDelay(float delay)

2.2 設置ViewGroup的子View播放動畫的順序

/*** Sets the order used to compute the delay of each child's animation.*/ void setOrder(int order)

setOrder可以取值為LayoutAnimationController.ORDER_NORMAL(正常順序),LayoutAnimationController.ORDER_RANDOM(隨機順序)以及LayoutAnimationController.ORDER_REVERSE(逆序)。這里的demo設置的是正常順序。

  • 3.播放動畫
/*** 播放RecyclerView動畫** @param animation* @param isReverse*/public void playLayoutAnimation(Animation animation, boolean isReverse) {LayoutAnimationController controller = new LayoutAnimationController(animation);controller.setDelay(0.1f);controller.setOrder(isReverse ? LayoutAnimationController.ORDER_REVERSE : LayoutAnimationController.ORDER_NORMAL);mRecyclerView.setLayoutAnimation(controller);mRecyclerView.getAdapter().notifyDataSetChanged();mRecyclerView.scheduleLayoutAnimation();}

通過viewGroup.setLayoutAnimation設置layout動畫。然后通知ViewGroup重新繪制,調用scheduleLayoutAnimation方法播放動畫。

(2)GridLayoutAnimationController

上述方法針對的是線性的RecyclerView,也就是說RecyclerView的LayoutManager設置的是LinearLayoutManager.

...@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_list);Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);mRecyclerView.setLayoutManager(new LinearLayoutManager(this));mRecyclerView.setAdapter(new DemoRecyclerViewAdapter());}...

而對于使用GridLayoutManager和StaggeredGridLayoutManager的RecyclerView來說,我們需要使用GridLayoutAnimationController,其他步驟與LayoutAnimationController一致。

...@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_grid);Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);mRecyclerView = (StaggeredGridRecyclerView) findViewById(R.id.recycler_view);mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));mStaggeredGridAdapter = new StaggeredGridAdapter();mStaggeredGridAdapter.setDataSet(mockData());mRecyclerView.setAdapter(mStaggeredGridAdapter);}....

同樣的,仍然使用之前的Animation創建GridLayoutAnimationController。

.../*** 播放動畫** @param animation* @param isReverse*/public void playLayoutAnimation(Animation animation, boolean isReverse) {GridLayoutAnimationController controller = new GridLayoutAnimationController(animation);controller.setColumnDelay(0.2f);controller.setRowDelay(0.3f);controller.setOrder(isReverse ? LayoutAnimationController.ORDER_REVERSE : LayoutAnimationController.ORDER_NORMAL);mRecyclerView.setLayoutAnimation(controller);mRecyclerView.getAdapter().notifyDataSetChanged();mRecyclerView.scheduleLayoutAnimation();}...

GridLayoutAnimationController的delay方法可以分別按照Column和Row維度進行設置。

本以為到此順利結束。運行后發現,會Crash,log為:

... E/AndroidRuntime( 7876): java.lang.ClassCastException: android.view.animation.LayoutAnimationController$AnimationParameters cannot be cast to android.view.animation.GridLayoutAnimationController$AnimationParameters E/AndroidRuntime( 7876): at android.view.animation.GridLayoutAnimationController.getDelayForView(GridLayoutAnimationController.java:299) E/AndroidRuntime( 7876): at android.view.animation.LayoutAnimationController.getAnimationForView(LayoutAnimationController.java:321) E/AndroidRuntime( 7876): at android.view.ViewGroup.bindLayoutAnimation(ViewGroup.java:4227) E/AndroidRuntime( 7876): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3272) E/AndroidRuntime( 7876): at android.view.View.draw(View.java:15618) E/AndroidRuntime( 7876): at android.support.v7.widget.RecyclerView.draw(RecyclerView.java:3869) E/AndroidRuntime( 7876): at android.view.View.updateDisplayListIfDirty(View.java:14495) E/AndroidRuntime( 7876): at android.view.View.getDisplayList(View.java:14524) E/AndroidRuntime( 7876): at android.view.View.draw(View.java:15315) E/AndroidRuntime( 7876): at android.view.ViewGroup.drawChild(ViewGroup.java:3536) E/AndroidRuntime( 7876): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3329) E/AndroidRuntime( 7876): at android.view.View.draw(View.java:15618) E/AndroidRuntime( 7876): at android.view.View.updateDisplayListIfDirty(View.java:14495) E/AndroidRuntime( 7876): at android.view.View.getDisplayList(View.java:14524) ...

為了解決這個問題,我們需要override RecyclerView的attachLayoutAnimationParameters方法:

package com.github.nuptboyzhb.recyclerviewanimation.grid;import android.content.Context; import android.support.annotation.Nullable; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.animation.GridLayoutAnimationController;/*** @version Created by haibozheng on 2016/12/9.* @Author Zheng Haibo* @Blog github.com/nuptboyzhb* @Company Alibaba Group* @Description StaggeredGridRecyclerView*/ public class StaggeredGridRecyclerView extends RecyclerView {public StaggeredGridRecyclerView(Context context) {super(context);}public StaggeredGridRecyclerView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public StaggeredGridRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}/*** 支持GridLayoutManager以及StaggeredGridLayoutManager** @param child* @param params* @param index* @param count*/@Overrideprotected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params,int index, int count) {LayoutManager layoutManager = this.getLayoutManager();if (getAdapter() != null && (layoutManager instanceof GridLayoutManager|| layoutManager instanceof StaggeredGridLayoutManager)) {GridLayoutAnimationController.AnimationParameters animationParams =(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;if (animationParams == null) {animationParams = new GridLayoutAnimationController.AnimationParameters();params.layoutAnimationParameters = animationParams;}int columns = 0;if (layoutManager instanceof GridLayoutManager) {columns = ((GridLayoutManager) layoutManager).getSpanCount();} else {columns = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();}animationParams.count = count;animationParams.index = index;animationParams.columnsCount = columns;animationParams.rowsCount = count / columns;final int invertedIndex = count - 1 - index;animationParams.column = columns - 1 - (invertedIndex % columns);animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns;} else {super.attachLayoutAnimationParameters(child, params, index, count);}} }

更多動畫效果,請參見Github源碼:https://github.com/nuptboyzhb/RecyclerViewAnimation

四、總結

通過LayoutAnimationController或者GridLayoutAnimationController來實現RecyclerView的動畫,非常簡單,而且效果很好。該方式不僅可以應用于RecyclerView,而且還適用于ListView、LinearLayout、GridView等ViewGroup。比如,如下是作用在一個LinearLayout的效果。




總結

以上是生活随笔為你收集整理的使用LayoutAnimationController为RecyclerView添加动画的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。