上篇「RecyclerView.Adapter優化了嗎?」主要講了RecyclerView.Adapter的優化代碼以及添加了item的click方法具體實現原理,這篇在原來的基礎上新增列表動畫,後續還會擴展更多功能,供你們學習,支持我就Star一下「BaseRecyclerViewAdapterHelper」。java
// 一行代碼搞定(默認爲漸顯效果) quickAdapter.openLoadAnimation();
若是你想換成別的效果你也能夠android
// 默認提供5種方法(漸顯、縮放、從下到上,從左到右、從右到左) quickAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN);
若是仍是不滿意則能夠自定義效果git
quickAdapter.openLoadAnimation(new BaseAnimation() { @Override public Animator[] getAnimators(View view) { return new Animator[]{ ObjectAnimator.ofFloat(view, "scaleY", 1, 1.1f, 1), ObjectAnimator.ofFloat(view, "scaleX", 1, 1.1f, 1) }; } });
使用就是如此簡單。github
首先先思考兩個問題算法
添加動畫在哪一個方法裏面添加?性能優化
如何控制動畫加載次數?ide
onBindViewHolder方法,由於每次填充數據的時候都會調用該方法。wordpress
private int mDuration = 300; public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { // 此處代碼省略,代碼已經在上篇詳細講解過了 if (isOpenAnimation) { BaseAnimation animation = null; if (customAnimation != null) { animation = customAnimation; }else{ animation = selectAnimation; } for (Animator anim : animation.getAnimators(holder.itemView)) { anim.setDuration(mDuration).start(); anim.setInterpolator(mInterpolator); } } }
以上代碼,首先判斷是否開啓動畫,而後判斷是不是自定義動畫仍是用戶選擇的自帶動畫,而後對動畫的操做元素進行遍歷執行,執行時間爲300毫秒,因爲上面說了每次填充數據都會調用,因此如何不判斷的話,就會致使上下滑動每次都會重複調用動畫,動畫自己是會耗費性能的。性能
private int mDuration = 300; private int mLastPosition = -1; private boolean isFirstOnly = true; public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { // 此處代碼省略,代碼已經在上篇詳細講解過了 if (isOpenAnimation) { if (!isFirstOnly || position > mLastPosition) { BaseAnimation animation = null; if (customAnimation != null) { animation = customAnimation; }else{ animation = selectAnimation; } for (Animator anim : animation.getAnimators(holder.itemView)) { anim.setDuration(mDuration).start(); anim.setInterpolator(mInterpolator); } mLastPosition = position; } } } public void setFirstOnly(boolean firstOnly) { isFirstOnly = firstOnly; }
只須要添加一個mLastPosition來存儲滑動過的位置,而後判斷滑動的位置是否被滑動過,這樣就能夠避免每次都添加動畫了。不過爲了知足喜歡動畫多過於性能的開發者,若是你想要每次滑動都帶動畫能夠設置isFirstOnly屬性便可,默認是不開啓的。學習
public abstract class BaseAnimation { public abstract Animator[] getAnimators(View view); }
public class AlphaInAnimation extends BaseAnimation { private static final float DEFAULT_ALPHA_FROM = 0f; private final float mFrom; public AlphaInAnimation() { this(DEFAULT_ALPHA_FROM); } public AlphaInAnimation(float from) { mFrom = from; } @Override public Animator[] getAnimators(View view) { return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f)}; } }
策略模式定義了一系列的算法,並將每個算法封裝起來,並且使它們還能夠相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。
在此採用的是「策略模式」,這樣更加靈活,若是須要自定義一個本身的動畫,只須要繼承BaseAnimation實現getAnimators方法便可。
public class CustomAnimation extends BaseAnimation { @Override public Animator[] getAnimators(View view) { return new Animator[]{ ObjectAnimator.ofFloat(view, "scaleY", 1, 1.1f, 1), ObjectAnimator.ofFloat(view, "scaleX", 1, 1.1f, 1) }; } }
設置便可
quickAdapter.openLoadAnimation(new CustomAnimation());
public void openLoadAnimation(@AnimationType int animationType)
在寫這個方法的時候,想是否是用枚舉更合適?可是曾看過多篇性能優化的文章不推薦Enum枚舉,由於性能消耗,其實Android有自帶的枚舉
官方文檔說明,安卓開發應避免使用Enum(枚舉類),由於相比於靜態常量Enum會花費兩倍以上的內存。
Android推薦,如下寫法
//先定義 常量 public static final int SUNDAY = 0; public static final int MONDAY = 1; public static final int TUESDAY = 2; public static final int WEDNESDAY = 3; public static final int THURSDAY = 4; public static final int FRIDAY = 5; public static final int SATURDAY = 6; //默認參數 @WeekDays int currentDay = SUNDAY; //用@IntDef "包住" 常量; // @Retention 定義策略 // 聲明構造器 @IntDef({SUNDAY, MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY}) @Retention(RetentionPolicy.SOURCE) public @interface WeekDays {} //設置參數 public void setCurrentDay(@WeekDays int currentDay) { this.currentDay = currentDay; }
aar包是 Android 的類庫項目的二進制發行包。
下拉框引用到別人的工程,引用方式是「arr包」
每次收穫一點點,後續還會擴展更多功能,供你們學習,支持我就Star一下「BaseRecyclerViewAdapterHelper」。