DefaultItemAnimator是Android OS中一個默認的RecyclerView動畫實現類,如果產品需求沒有特別復雜的動畫要求,可以使用DefaultItemAnimator實現簡單的動畫效果。DefaultItemAnimator動畫的實現流程和原理已經在上兩節中做過簡單介紹,如果還沒有看過的童鞋,最好先打眼掃一下之前兩節的內容,有助於理解。附上鏈接地址:
1RecyclerView.ItemAnimator終極解讀(一)--RecyclerView源碼解析
2RecyclerView.ItemAnimator終極解讀(二)--SimpleItemAnimator和DefaultItemAnimator源碼解析
這一節,我們主要通過繼承DefaultItemAnimator來實現稍微復雜一點的自定義動畫。效果如下兩張圖所示:
如上兩張圖所示:每點擊一個item時,更新所點擊item的背景顏色和文本信息。 第一張圖是沒有添加動畫效果, 第二張圖是添加自定義動畫之後的效果。
主要代碼就是在自定義的動畫類MyDefaultItemAnimator.java中, 如下所示:
package material.danny_jiang.com.mydefaultitemanimator;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.NonNull;
import android.support.v4.util.ArrayMap;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
/**
* Created by axing on 16/5/25.
*/
public class MyDefaultItemAnimator extends DefaultItemAnimator {
private static final String TAG = "MyDefaultItemAnimator";
// 定義動畫執行時的加速度
private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
private DecelerateInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
ArgbEvaluator mColorEvaluator = new ArgbEvaluator();
/**
* 定義正在執行Animator的ViewHolder的Map集合
* 此集合會保存用戶點擊的ViewHolder對象,目的在於當用戶不停的點擊某一item時
* 會先判斷此ViewHolder種的itemView動畫是否正在執行,如果正在執行則停止
*/
private ArrayMap mAnimatorMap = new ArrayMap<>();
/**
* 復寫canReuseUpdatedViewHolder方法並返回true,通知RecyclerView在執行動畫時可以復用ViewHolder對象
* @param viewHolder
* @return
*/
@Override
public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder) {
return true;
}
/**
* 自定義getItemHolderInfo方法,將ViewHolder中的背景顏色和TextView的文本信息傳入ColorTextInfo中
* @param viewHolder
* @param info
* @return
*/
@NonNull
private ItemHolderInfo getItemHolderInfo(MyViewHolder viewHolder, ColorTextInfo info) {
//獲取當前正在操作的ViewHolder對象
final MyViewHolder myHolder = viewHolder;
//獲取ViewHolder中itemView背景顏色
final int bgColor = ((ColorDrawable) myHolder.container.getBackground()).getColor();
//將背景顏色和TextView的文本信息賦值給ColorTextInfo對象的color和text變量
info.color = bgColor;
info.text = (String) myHolder.textView.getText();
return info;
}
/**
* 通過ViewHolder對象獲取動畫執行之前itemView中的背景顏色和文本信息
* 初始化ColorTextInfo對象,並將背景顏色和文本信息進行賦值
* @return
*/
@NonNull
@Override
public ItemHolderInfo recordPreLayoutInformation(RecyclerView.State state,
RecyclerView.ViewHolder viewHolder, int changeFlags, List
每段代碼的含義的用途都已經在代碼中添加了相應的注釋,請耐得住寂寞,仔細查看^_^
自定義ItemAnimator實現好之後,剩下的就是初始化RecyclerView,並通過setItemAnimator方法將自定義ItemAnimator對象傳遞給RecyclerView。
MainActivity.java中的相關代碼如下:
recyclerView = ((RecyclerView) findViewById(R.id.recyclerview));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new RecyclerAdapter(this, recyclerView));
recyclerView.setItemAnimator(new MyDefaultItemAnimator());
RecyclerAdapter.java代碼如下:
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final MyViewHolder myHolder = (MyViewHolder) holder;
int color = mColors.get(position);
myHolder.container.setBackgroundColor(color);
myHolder.textView.setText("#" + Integer.toHexString(color));
}
@Override
public int getItemCount() {
return mColors.size();
}
private View.OnClickListener mItemAction = new View.OnClickListener() {
@Override
public void onClick(View v) {
changeItem(v);
}
};
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View container = mainActivity.getLayoutInflater().inflate(R.layout.item_layout, parent, false);
container.setOnClickListener(mItemAction);
return new MyViewHolder(container);
}
private int generateColor() {
int red = ((int) (Math.random() * 200));
int green = ((int) (Math.random() * 200));
int blue = ((int) (Math.random() * 200));
return Color.rgb(red, green, blue);
}
private void generateData() {
for (int i = 0; i < 100; ++i) {
mColors.add(generateColor());
}
}
private void changeItem(View view) {
int position = mRecyclerView.getChildAdapterPosition(view);
if (position != RecyclerView.NO_POSITION) {
int color = generateColor();
mColors.set(position, color);
notifyItemChanged(position);
}
}
MyViewHolder.java代碼如下:
package material.danny_jiang.com.mydefaultitemanimator;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Created by axing on 16/5/25.
*/
class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public LinearLayout container;
public MyViewHolder(View v) {
super(v);
container = (LinearLayout) v;
textView = (TextView) v.findViewById(R.id.textview);
}
@Override
public String toString() {
return super.toString() + " \"" + textView.getText() + "\"";
}
}