Android 中RecyclerView通用适配器的实现
Android 中RecyclerView通用适配器的实现
前言:
SDK的5.0版本出来已经N久了,可以说是已经经过许多人的检验了,里面的新控件不能说是非常完美,但也是非常好用了,其中最让我喜爱的就是RecyclerView了,可以完美替代ListView和GridView(除了添加headerview和footview了,网上有许多解决方式。这个下面会以一种简单的方式顺带解决,肯定为大家省心),而且可以代码动态切换这两种布局方式以及瀑布流布局。相关切换方式网上有很多,大家自行搜索,我就不贴连接了。
相信大家在之前使用listview时肯定一直很厌烦重复编写无数的adapter,当然有那么一部分机智如我的人肯定一直使用着万能适配器。然而RecyclerView要求我们必须使用ViewHolder来实现adapter。这就让许多用惯了万能适配器的人不爽了。今天我就提供一直基于listview万能适配器的实现原理来改良实现的RecyclerView的通用适配器,由于不是教学,切代码比较简单,就不分段讲解了,相信大家看注释就能看懂。
一共两个类,一个是继承了系统的Android.support.v7.widget.RecyclerView.ViewHolder所实现的RViewHolder类,通过他实现任意控件的缓存一个是继承了android.support.v7.widget.RecyclerView.Adapter所实现的RBaseAdapter类。
实现代码:
RViewHolder
import android.content.Context; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView.ViewHolder; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; public class RViewHolder extends ViewHolder { private Context mContext; private View mConvertView; private SparseArray<View> mViews; public RViewHolder(View itemView) { super(itemView); mConvertView = itemView; this.mViews = new SparseArray<View>(); } public static RViewHolder get(Context context, ViewGroup parent, int layoutId, int position) { View view = LayoutInflater.from(context).inflate(layoutId, parent, false); return new RViewHolder(view); } /** * 通过控件的Id获取对于的控件,如果没有则加入views * * @param viewId * @return */ public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (view == null) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } /** * 为TextView设置字符�? * * @param viewId * @param text * @return */ public ViewHolder setText(int viewId, String text) { TextView view = getView(viewId); view.setText(text); return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */ public ViewHolder setImageResource(int viewId, int drawableId) { ImageView view = getView(viewId); view.setImageResource(drawableId); return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */ public ViewHolder setImageBitmap(int viewId, Bitmap bm) { ImageView view = getView(viewId); view.setImageBitmap(bm); return this; } public View getConvertView() { return mConvertView; } }
这里是RBaseAdapter
import java.util.ArrayList; import java.util.Collection; import java.util.List; import android.content.Context; import android.support.v7.widget.RecyclerView.Adapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; public abstract class RBaseAdapter<T> extends Adapter<RViewHolder> { private Context mContext; private List<T> list; protected LayoutInflater mInflater; private int mItemLayoutId; public RBaseAdapter(Context context) { // TODO Auto-generated constructor stub this.mContext = context; this.mInflater = LayoutInflater.from(mContext); this.mItemLayoutId = new LinearLayout(mContext).getId(); this.list = new ArrayList<T>(); } public RBaseAdapter(Context context, List<T> list) { // TODO Auto-generated constructor stub this.mContext = context; this.mInflater = LayoutInflater.from(mContext); this.mItemLayoutId = new LinearLayout(mContext).getId(); this.list = list; } public RBaseAdapter(Context context, List<T> list, int itemLayoutId) { this.mContext = context; this.mInflater = LayoutInflater.from(mContext); this.mItemLayoutId = itemLayoutId; this.list = list; } public RBaseAdapter(Context context, int itemLayoutId) { this.mContext = context; this.mInflater = LayoutInflater.from(mContext); this.mItemLayoutId = itemLayoutId; this.list = new ArrayList<T>(); } public void setitemLayoutId(int itemLayoutId) { this.mItemLayoutId = itemLayoutId; } public List<T> getList() { return this.list; } public void appendList(List<T> list) { // TODO Auto-generated method stub this.list = list; notifyDataSetChanged(); } public void addList(List<T> list2) { // TODO Auto-generated method stub this.list.addAll((Collection<? extends T>) list2); notifyDataSetChanged(); } @Override public int getItemCount() { return list.size(); } boolean hasHeader = false; boolean hasFooter = false; View headerView; View footerView; public void setHeaderView(View headerView) { hasHeader=true; this.headerView = headerView; } public void setFooterView(View footerView) { hasFooter = true; this.footerView = footerView; } public View getHeaderView() { return headerView; } public View getFooterView() { return footerView; } @Override public void onBindViewHolder(RViewHolder holder, int position) { if (hasHeader && position == 0) { return; } else if (hasFooter && position == (list.size() + (hasHeader ? 1 : 0))) { return; } else convert(holder, (T) list.get(position)); } @Override public RViewHolder onCreateViewHolder(ViewGroup parent, int position) { if (hasHeader && position == 0) { return new RViewHolder(headerView); } else if (hasFooter && position == (list.size() + (hasHeader ? 1 : 0))) { return new RViewHolder(footerView); } else return RViewHolder.get(mContext, parent, mItemLayoutId, position); } //这里定义抽象方法,我们在匿名内部类实现的时候实现此方法来调用控件 public abstract void convert(RViewHolder holder, T item); }
对于RBaseAdapter稍微讲解下,首先是泛型,这样任何对象类型都可以使用,再来就是前面提到的headerview和footerview的解决,可以看到RBaseAdapter里面定义了几个方法,通过position的不同来加载不同的布局的思想来添加headerview和footerview。
Activity里面调用
recyclerView.setAdapter(new RBaseAdapter<VirtualWinsBean>(mContext, R.layout.virtual_win_users_list_item) { @Override public void convert(RViewHolder holder, VirtualWinsBean item) { if (Util.checkNULL(item.getNick_name())) { holder.setText(R.id.name, Util.HidePhone(item.getPhone() + "")); } else { holder.setText(R.id.name, item.getNick_name()); } RoundImageView networkImageView = holder.getView(R.id.photo); networkImageView.setLoadingImage(R.drawable.header_def); networkImageView.setDefultImage(R.drawable.header_def); networkImageView.LoadUrl(U.g(item.getFile_url())); } });
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!