您的位置:首页 > 其它

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);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: