>上篇「[RecyclerView.Adapter優化了嗎?](http://blog.csdn.net/cym492224103/article/details/51113321)」主要講了RecyclerView.Adapter的優化代碼以及添加了item的click方法具體實現原理,這篇在原來的基礎上新增列表動畫,后續還會擴展更多功能,供大家學習,支持我就Star一下「[BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)」。
##效果如何?



##如何使用?
```
// 一行代碼搞定(默認為漸顯效果)
quickAdapter.openLoadAnimation();
```
如果你想換成別的效果你也可以
```
// 默認提供5種方法(漸顯、縮放、從下到上,從左到右、從右到左)
quickAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN);
```
如果還是不滿意則可以自定義效果
```
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)
};
}
});
```
使用就是如此簡單。
##如何做到的?
>首先先思考兩個問題
- **添加動畫在哪個方法里面添加?**
- **如何控制動畫加載次數?**
###添加動畫在哪個方法里面添加?
onBindViewHolder方法,因為每次填充數據的時候都會調用該方法。
```
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屬性即可,默認是不開啟的。
##Animation的設計
###BaseAnimation
```
public abstract class BaseAnimation {
public abstract Animator[] getAnimators(View view);
}
```
###AlphaInAnimation
```
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());
```
##小知識
###openLoadAnimation方法
```
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;
}
```
詳細文章可查看
https://noobcoderblog.wordpress.com/2015/04/12/java-enum-and-android-intdefstringdef-annotation/
###下拉框的引用
>aar包是 Android 的類庫項目的二進制發行包。
下拉框引用到別人的工程,引用方式是「arr包」
---
>每次收獲一點點,后續還會擴展更多功能,供大家學習,支持我就Star一下「[BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)」。