BaseRecyclerViewAdapterHelper源码解读(一) 封装简单的adapter和万能的BaseViewHolder
2017-10-18 16:42
537 查看
BaseRecyclerViewAdapterHelper源码解读(一)
1. 封装万能的BaseViewHolder
这是所有ViewHolder的父类通过SparseArray存储item布局中的控件
通过getView()去获取控件,如果在SparseArray中存在则直接获取,如果不存在则findViewById()然后再插入SparseArray中
设置一些常用操作:设置文本,点击事件,颜色….
SparseArray比HashMap更省内存,在某些条件下性能更好,主要是因为它避免了对key的自动装箱(int转为Integer类型),它内部则是通过两个数组来进行数据存储的,一个存储key,另外一个存储value,为了优化性能,它内部对数据还采取了压缩的方式来表示稀疏数组的数据,从而节约内存空间.
import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.support.annotation.ColorLong; import android.support.annotation.DrawableRes; import android.support.annotation.FloatRange; import android.support.annotation.IdRes; import android.support.annotation.NonNull; import android.support.annotation.StringRes; import android.support.v7.widget.RecyclerView; import android.text.SpannableStringBuilder; import android.util.SparseArray; import android.view.View; import android.widget.Checkable; import android.widget.ImageView; import android.widget.TextView; /** * author xingyun * create at 2017/9/26 16:54 * description:适用所有RecyclerView的ViewHolder */ public class BaseViewHolder extends RecyclerView.ViewHolder { //子布局中的控件 private SparseArray<View> mItemViews; //子布局 private View mView; //初始化ViewHolder public BaseViewHolder(View itemView) { super(itemView); mView = itemView; mItemViews = new SparseArray<>(); } /** * 获取子控件 * <p> * 子控件的id * * @param viewId 返回子控件 * @return */ public View getView(@IdRes int viewId) { View view = mItemViews.get(viewId); if (view == null) { view = mView.findViewById(viewId); mItemViews.put(viewId, view); } return view; } /** * 通过strings.xml文件给TextView设置文本 * <p> * 子控件的id * * @param viewId 子控件在strings.xml中的文本 * @param resId 返回子控件 * @return BaseViewHolder */ public BaseViewHolder setText(@IdRes int viewId, @StringRes int resId) { TextView textView = (TextView) getView(viewId); textView.setText(resId); return this; } /** * 通过String给TextView设置文本 * <p> * 子控件的id * * @param viewId 子控件中的文本 * @param text 返回子控件 * @return BaseViewHolder */ public BaseViewHolder setText(@IdRes int viewId, String text) { TextView textView = (TextView) getView(viewId); if (text != null) { textView.setText(text); } else { textView.setText(""); } return this; } /** * 通过SpannableStringBuilder给TextView设置文本 * * @param viewId View的id * @param text 文本 * @return BaseViewHolder */ public BaseViewHolder setText(@IdRes int viewId, SpannableStringBuilder text) { TextView textView = (TextView) getView(viewId); if (text != null) { textView.setText(text); } else { textView.setText(""); } return this; } /** * 通过drawable文件夹中的资源设置图片 * * @param viewId view的id * @param resId 文本 * @return BaseViewHolder */ public BaseViewHolder setImageResource(@IdRes int viewId, @DrawableRes int resId) { ImageView imageView = (ImageView) getView(viewId); imageView.setImageResource(resId); return this; } /** * 通过Bitmap设置图片 * * @param viewId view Id * @param bitmap Bitmap * @return BaseViewHolder */ public BaseViewHolder setImageBitmap(@IdRes int viewId, @NonNull Bitmap bitmap) { ImageView imageView = (ImageView) getView(viewId); if (bitmap != null) { imageView.setImageBitmap(bitmap); } return this; } /** * 通过Drawable设置图片 * * @param viewId View的id * @param drawable Drawable * @return BaseViewHolder */ public BaseViewHolder setImageDrawable(@IdRes int viewId, @NonNull Drawable drawable) { ImageView imageView = (ImageView) getView(viewId); if (drawable != null) { imageView.setImageDrawable(drawable); } return this; } /** * 通过一串数字设置背景色 * * @param viewId View的id * @param color 颜色值 16进制 * @return BaseViewHolder */ public BaseViewHolder setBackgroundColor(@IdRes int viewId, @ColorLong int color) { View view = getView(viewId); view.setBackgroundColor(color); return this; } /** * 通过drawable文件夹设置背景图 * * @param viewId View的id * @param backgroundRes Resource * @return BaseViewHolder */ public BaseViewHolder setBackgroundResource(@IdRes int viewId, @DrawableRes int backgroundRes) { View view = getView(viewId); view.setBackgroundResource(backgroundRes); return this; } /** * 通过Drawable设置背景图 * * @param viewId View的id * @param drawable Drawable * @return BaseViewHolder */ public BaseViewHolder setBackgroundDrawable(@IdRes int viewId, Drawable drawable) { View view = getView(viewId); if (drawable != null) { view.setBackground(drawable); } return this; } /** * 通过一串数字设置文字颜色 * * @param viewId View的id * @param textColor 颜色值 16进制 * @return BaseViewHolder */ public BaseViewHolder setTextColor(@IdRes int viewId, @ColorLong int textColor) { TextView textView = (TextView) getView(viewId); textView.setTextColor(textColor); return this; } /** * 通过float设置透明度 * * @param viewId View的id * @param value 透明度 范围:[0.0,1.0] * @return BaseViewHolder */ public BaseViewHolder setAlpha(@IdRes int viewId, @FloatRange(from = 0.0, to = 1.0) float value) { getView(viewId).setAlpha(value); return this; } /** * 通过boolean类型设置是否显示 * * @param viewId View的id * @param visible 是否可见 true:可见; false:不可见,Gone * @return BaseViewHolder */ public BaseViewHolder setVisible(@IdRes int viewId, boolean visible) { View view = getView(viewId); view.setVisibility(visible ? view.VISIBLE : View.GONE); return this; } /** * 缓存子控件上界面的数据 * * @param viewId View的id * @param tag 需要缓存的数据 * @return BaseViewHolder */ public BaseViewHolder setTag(@IdRes int viewId, Object tag) { View view = getView(viewId); view.setTag(tag); return this; } /** * 设置某一位置子控件的数据 * * @param viewId View的id * @param key 数据标识 * @param tag 数据 * @return BaseViewHolder */ public BaseViewHolder setTag(@IdRes int viewId, int key, Object tag) { View view = getView(viewId); view.setTag(key, tag); return this; } /** * 设置子控件是否选中 * * @param viewId View的id * @param checked true:选中 false:未选中 * @return BaseViewHolder */ public BaseViewHolder setChecked(@IdRes int viewId, boolean checked) { Checkable checkable = (Checkable) getView(viewId); checkable.setChecked(checked); return this; } /** * 设置子控件的点击事件 * * @param viewId View的id * @param listener OnClickListener监听器 * @return BaseViewHolder */ public BaseViewHolder setOnClickListener(@IdRes int viewId, @NonNull View.OnClickListener listener) { View view = getView(viewId); if (listener != null) { view.setOnClickListener(listener); } return this; } /** * 设置子控件的触摸事件 * * @param viewId View的id * @param listener OnTouchListener * @return BaseViewHolder */ public BaseViewHolder setOnTouchListener(@IdRes int viewId, @NonNull View.OnTouchListener listener) { View view = getView(viewId); if (listener != null) { view.setOnTouchListener(listener); } return this; } /** * 设置子控件的长按事件 * * @param viewId View的id * @param listener OnLongClickListener * @return BaseViewHolder */ public BaseViewHolder setOnLongClickListener(@IdRes int viewId, @NonNull View .OnLongClickListener listener) { View view = getView(viewId); if (listener != null) { view.setOnLongClickListener(listener); } return this; } }
2. 封装简单的Adapter
将重复的方法那些全部抽取到父类(Abstract)免得每次都重复写父类的泛型是 Bean对象,BaseViewHolder
在onCreateViewHolder()里面写点击事件比较好,因为在onBindViewHolder()里面写的话,每次都要去绑定,会产生多余的消耗.
然后onBindViewHolder()方法是需要每个子类去实现的,我们可以提供一个convert()方法在里面,暴露给外面实现,用于绑定数据.
添加item,移除item->封装
然后封装item点击事件,item长按事件
package com.xfhy.basequickadapter; import android.content.Context; import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.List; /** * author feiyang * create at 2017/10/16 15:45 * description: */ public abstract class BaseQuickAdapter<T, K extends BaseViewHolder> extends RecyclerView .Adapter<K> { private Context mContext; /** * 数据集合 */ private List<T> dataList; /** * RecyclerView中普通item的布局id */ private int layoutResId; /** * 子项item点击事件 */ private OnItemClickListener onItemClickListener; /** * 子项item长按事件 */ private OnItemLongClickListener onItemLongClickListener; public BaseQuickAdapter(Context context) { this.mContext = context; } /** * 此构造方法必须调用 * * @param context Context * @param layoutResId 子项普通item布局 * @param dataList 子项数据集合 */ public BaseQuickAdapter(Context context, int layoutResId, List<T> dataList) { this.mContext = context; this.layoutResId = layoutResId; this.dataList = dataList; } @Override public K onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(layoutResId, parent, false); final BaseViewHolder baseViewHolder = new BaseViewHolder(view); // item点击事件 if (onItemClickListener != null) { view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onItemClickListener.onItemClick(v, baseViewHolder.getLayoutPosition()); } }); } // item长按事件 if (onItemLongClickListener != null) { view.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { return onItemLongClickListener.onLongClick(v, baseViewHolder .getLayoutPosition()); } }); } return (K) baseViewHolder; } @Override public void onBindViewHolder(K holder, int position) { convert(holder, dataList.get(position)); } @Override public int getItemCount() { return dataList == null ? 0 : dataList.size(); } /** * 绑定数据 * * @param holder BaseViewHolder * @param item item数据 */ protected abstract void convert(BaseViewHolder holder, T item); /** * 设置item点击事件 * * @param onItemClickListener OnItemClickListener */ public void setOnItemClickListener(@NonNull OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } /** * 设置item长按事件 * * @param onItemLongClickListener OnItemLongClickListener */ public void setOnItemLongClickListener(@NonNull OnItemLongClickListener onItemLongClickListener) { this.onItemLongClickListener = onItemLongClickListener; } /** * item点击监听器 */ public interface OnItemClickListener { /** * item点击事件回调 * * @param view 触发事件View * @param position 触发事件的view所在RecyclerView中的位置 */ void onItemClick(View view, int position); } /** * item长按监听器 */ public interface OnItemLongClickListener { /** * item长按事件回调 * * @param view 触发事件View * @param position 触发事件的view所在RecyclerView中的位置 * @return 是否消费 */ boolean onLongClick(View view, int position); } /** * 删除item * * @param position 删除item的位置 */ public void removeItem(@IntRange(from = 0) int position) { if (dataList == null) { return; } if (position >= dataList.size()) { return; } dataList.remove(position); notifyItemRemoved(position); } /** * 新增item * * @param position 新增item位置 * @param item item数据 */ public void addItem(@IntRange(from = 0) int position, @NonNull T item) { if (dataList == null) { return; } if (position > dataList.size()) { return; } dataList.add(position, item); notifyItemInserted(position); } }
相关文章推荐
- 封装好的万能ViewHolder和Adapter
- ViewHolder baseadatper封装的万能适配器
- Android-万能 Adapter 封装(实现textview,imageView 的简单封装,封装 jar 包)
- 简单的封装BaseRecycleviewAdapter
- 对BaseAdapter和ViewHolder的封装
- 自定义封装了ViewHolder的BaseAdapter,简化了Adapter的编写
- BaseAdapter的最简单的封装
- Error:(13, 8) 错误: xxx不是抽象的, 并且未覆盖xxx中的抽象方法onBindViewHolder(BaseSimpleRecyclerAdapter.ViewHolder,int)
- 基于RecyclerView的BaseAdapter、ViewHolder、OnItemClickListener联合使用
- Android中的自定义Adapter(继承自BaseAdapter)——与系统Adapter的调用方法一致——含ViewHolder显示效率的优化
- BaseRecyclerViewAdapterHelper简单使用
- Android中的自定义Adapter(继承自BaseAdapter)——与系统Adapter的调用方法一致——含ViewHolder显示效率的优化(转)
- 超级简单RecycleViewAdapter的封装-支持多视图,多点击回调
- BaseRecycleViewAdapter的封装,基于多种bean数据源的呈现
- Android 自定义全局baseAdapter和ViewHolder
- 偷懒新姿势,打造属于RecyclerView的万能适配器Adapter和ViewHolder
- BaseAdapter深入学习,不规则listview,ListView加载性能优化ViewHolder
- ListView之BaseAdapter的基本使用以及ViewHolder模式
- ListView之BaseAdapter的基本使用以及ViewHolder模式
- RecyclerView 封装Adapter之BaseRecyclerAdapter