在使用RecyclerView的时候,会重复编写adapter代码,需要封装下。写得比较潦草,下面代码赋值直接用。
封装RecyclerView
封装ViewHolder类
public class BaseRecycleViewHolder extends RecyclerView.ViewHolder {
// 整个列表项的根视图
private View mConvertView;
// 存储视图SparseArray集合,这是轻量级键值对
private SparseArray<View> mView;
/**
* 构造函数,初始化 ViewHolder。
* @param itemView 列表项的根视图
*/
public BaseRecycleViewHolder(@NonNull View itemView) {
super(itemView);
mView = new SparseArray<>();
mConvertView = itemView;
}
/**
* 获取整个列表项的根视图。
* @return 整个列表项的根视图
*/
public View getConvertView() {
return mConvertView;
}
/**
* 通过控件的资源ID获取该控件。
*
* @param viewId 控件的资源ID
* @param <T> 控件的类型
* @return 通过资源ID获取到的控件
*/
public <T extends View> T getView(int viewId) {
View view = mView.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mView.put(viewId, view);
}
return (T) view;
}
}
封装RecyclerViewAdapter类
public abstract class BaseRecyclerViewAdapter<T,VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
protected Context mContext;
protected List<T> mList;
protected OnItemClickListener mOnitemClickListener;
protected OnItemSeekBarChangeListener mOnItemSeekBarChangeListener;
public BaseRecyclerViewAdapter(Context context) {
mContext = context;
}
public void setData(List<T> list) {
mList = list;
notifyDataSetChanged();
}
public synchronized void addData(List<T> list) {
if (mList==null)
mList = new ArrayList();
if (list != null) {
mList.addAll(list);
notifyDataSetChanged();
}
}
public synchronized void addData(T object) {
if (mList==null)
mList = new ArrayList();
if (object != null) {
mList.add(object);
notifyDataSetChanged();
}
}
public void clearData() {
if (mList != null) {
mList.clear();
}
notifyDataSetChanged();
}
public void setOnItemClickListener(OnItemClickListener listener) {
mOnitemClickListener=listener;
}
public void setOnItemSeekBarChangeListener(OnItemSeekBarChangeListener listener) {
mOnItemSeekBarChangeListener=listener;
}
public List getData() {
return mList;
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
@Override
public int getItemCount() {
return mList == null ? 0 : mList.size();
}
public interface OnItemClickListener {
void onItemClick(View view, List list, int position);
}
public interface OnItemSeekBarChangeListener {
void onItemClick(View view, int v, int position);
}
}
使用适配器类
class MyAdapter(val context: Context) : BaseRecyclerViewAdapter<String, BaseRecycleViewHolder>(context) {
var TAG = "FavoriteAdapter"
// 空数据时,显示空布局类型
private val TYPE_EMPTY = 1
// 正常数据
private val TYPE_NORMAL = 0
override fun getItemViewType(position: Int): Int {
if (mList == null || mList?.size!! <= 0) {
return TYPE_EMPTY;
}
return TYPE_NORMAL;
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseRecycleViewHolder {
val view: View;
//若为空布局类型,则直接返回空的RecyclerView.ViewHolder
if (viewType == TYPE_EMPTY) {
view = LayoutInflater.from(context).inflate(R.layout.item_empty, parent, false);
return EmptyViewHolder(view)
}
view = LayoutInflater.from(context).inflate(R.layout.item_wallpaper, parent, false)
val viewHolder = BaseRecycleViewHolder(view)
viewHolder.convertView.setOnClickListener {
mOnItemClickListener.onItemClick(view, viewHolder.adapterPosition)
}
return viewHolder
}
override fun onBindViewHolder(holder: BaseRecycleViewHolder, position: Int) {
if (mList != null && mList.size > 0) {
// 可以进行设置值,这里我不赋值了
val data = mList.get(position)
// 图片
(holder.getView<View>(R.id.img_wallpaper) as ImageView)
// 播放图片按钮
(holder.getView<View>(R.id.img_play) as ImageView)
// 图片总数
(holder.getView<View>(R.id.tv_count) as TextView)
// 收藏图片按钮
(holder.getView<View>(R.id.img_favorite) as ImageView)
}
}
override fun getItemCount(): Int {
if (mList.size == 0) {
return TYPE_EMPTY;
}
return mList.size
}
inner class EmptyViewHolder(itemView: View) : BaseRecycleViewHolder(itemView) {
}
}
然后在给RecyclerView.adapter的时候调用,调用adapter.setData(listData)就可以填充数据。
--------------------------------------------------2024.3.7--------------------------------------------------
今天看到一篇文章,快来封装RecyclerView通用适配器Adapter_recyclerview通用 adapter-CSDN博客 ,因此我借鉴改了一下,进行优化。在最后使用适配器类的时候,只要实现一个方法就可以了,节省了很多代码。
优化
BaseRecycleViewHolder
public class BaseRecycleViewHolder extends RecyclerView.ViewHolder {
// 整个列表项的根视图
private View mConvertView;
// 存储视图SparseArray集合,这是轻量级键值对
private SparseArray<View> mView;
/**
* 构造函数,初始化 ViewHolder。
* @param itemView 列表项的根视图
*/
public BaseRecycleViewHolder(@NonNull View itemView) {
super(itemView);
mView = new SparseArray<>();
mConvertView = itemView;
}
/**
* 获取整个列表项的根视图。
* @return 整个列表项的根视图
*/
public View getConvertView() {
return mConvertView;
}
/**
* 通过控件的资源ID获取该控件。
*
* @param viewId 控件的资源ID
* @param <T> 控件的类型
* @return 通过资源ID获取到的控件
*/
public <T extends View> T getView(int viewId) {
View view = mView.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mView.put(viewId, view);
}
return (T) view;
}
}
BaseRecyclerViewAdapter
public abstract class BaseRecyclerViewAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements View.OnClickListener {
// 上下文对象
protected Context mContext;
// 数据列表
protected List<T> mList;
// 布局id
private int mLayoutId;
// 空数据时,显示空布局类型
private final int TYPE_EMPTY = 1;
// 正常数据
private final int TYPE_NORMAL = 0;
// item点击事件(这是自定义的)
protected OnItemClickListener mOnItemClickListener;
protected OnItemChildClickListener mOnItemChildClickListener;
/**
* 构造函数,初始化适配器,传入上下文对象。
*
* @param context 上下文对象
*/
public BaseRecyclerViewAdapter(Context context, int layoutId) {
mContext = context;
mLayoutId = layoutId;
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
//若为空布局类型,则直接返回空的RecyclerView.ViewHolder
if (viewType == TYPE_EMPTY) {
view = LayoutInflater.from(mContext).inflate(R.layout.item_empty, parent, false);
return (VH) new EmptyViewHolder(view);
} else {
view = LayoutInflater.from(mContext).inflate(mLayoutId, parent, false);
// 设置点击事件
view.setOnClickListener(this);
}
return (VH) new BaseRecycleViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {
holder.itemView.setTag(position);
if (mList != null && mList.size() > 0) {
T bean = mList.get(position);
onBindData(holder, bean, position);
}
}
public abstract void onBindData(VH holder, T bean, int position);
@Override
public void onClick(View v) {
if(mOnItemClickListener!=null) {
mOnItemClickListener.onItemClick(v, (Integer) v.getTag());
}
}
/**
* 获取指定位置项的视图类型。
*
* @param position 项的位置
* @return 视图类型
*/
@Override
public int getItemViewType(int position) {
if (mList == null || mList.size() <= 0) {
return TYPE_EMPTY;
}
return TYPE_NORMAL;
}
/**
* 获取适配器中的项数。
*
* @return 项数
*/
@Override
public int getItemCount() {
if (mList!=null && mList.size() == 0) {
return TYPE_EMPTY;
}
return mList.size();
}
/**
* 设置列表项点击事件监听器。
*/
public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
/**
* 设置子项内部控件点击事件监听器。
*/
public void setOnItemChildClickListener(OnItemChildClickListener mOnItemClickListener) {
this.mOnItemChildClickListener = mOnItemClickListener;
}
/**
* 获取适配器中的数据列表。
*
* @return 数据列表
*/
public List<T> getData() {
return mList;
}
/**
* 设置适配器的数据列表,并通知适配器数据发生变化。
*
* @param list 新的数据列表
*/
public void setData(List<T> list) {
mList = list;
notifyDataSetChanged();
}
/**
* 同步地向适配器中添加数据列表,并通知适配器数据发生变化。
* @param list 要添加的数据列表
*/
public synchronized void addData(List<T> list) {
if (mList == null)
mList = new ArrayList();
if (list != null) {
mList.addAll(list);
notifyDataSetChanged();
}
}
/**
* 同步地向适配器中添加单个数据项,并通知适配器数据发生变化。
*
* @param object 要添加的数据项
*/
public synchronized void addData(T object) {
if (mList == null)
mList = new ArrayList();
if (object != null) {
mList.add(object);
notifyDataSetChanged();
}
}
/**
* 清空适配器中的数据列表,并通知适配器数据发生变化。
*/
public void clearData() {
if (mList != null) {
mList.clear();
}
notifyDataSetChanged();
}
/**
* ViewHolder 用于空布局
*/
private static class EmptyViewHolder extends RecyclerView.ViewHolder {
// 在这里添加空布局的控件,例如一个 TextView
private TextView emptyTextView;
public EmptyViewHolder(@NonNull View itemView) {
super(itemView);
// 初始化空布局的控件
emptyTextView = itemView.findViewById(R.id.tv_empty);
}
}
}
使用适配器类
class MyAdapter(val context: Context) : BaseRecyclerViewAdapter<String, BaseRecycleViewHolder>(context,R.layout.item_wallpaper) {
var TAG = "MyAdapter"
override fun onBindData(holder: BaseRecycleViewHolder?, bean: String?, position: Int) {
if (mList != null && mList.size > 0) {
val data = mList.get(position)
// 可以进行赋值
// 图片
(holder?.getView<View>(R.id.img_wallpaper) as ImageView)
// 播放图片按钮
(holder.getView<View>(R.id.img_play) as ImageView)
// 图片总数
(holder.getView<View>(R.id.tv_count) as TextView)
// 收藏图片按钮
(holder.getView<View>(R.id.img_favorite) as ImageView)
}
}
}
然后在给RecyclerView.adapter的时候调用,调用adapter.setData(listData)就可以填充数据。