RecyclerView.Adapter优化
2016-10-19 本文已影响219人
比萨u
缘由
最近项目我在项目中使用了RecyclerView代替了ListView。
其实,怎么说呢?就是懒,想少写代码,所以想研究一下能否简化一下.
分两种
-
第一种支持Butterknife(黄油刀)快速生成ViewHolder
封装的父类RvBaseAdapter
public abstract class RvBaseAdapter<T, V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V> {
public List<T> data;
public Context context;
public RvBaseAdapter(List<T> data, Context context) {
this.data = data;
this.context = context;
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public V onCreateViewHolder(ViewGroup parent, int viewType) {
return onCreateViewHolder(LayoutInflater.from(context).inflate(getLayout(viewType), null));
}
/**
* 获得布局文件
* @return
*/
protected abstract int getLayout(int viewType);
/**
* 创建一个ViewHolder
* @param convertView View
* @return
*/
protected abstract V onCreateViewHolder(View convertView);
/**
* 绑定ViewHolder
* @param holder ViewHolder
* @param position 位置
*/
@Override
public abstract void onBindViewHolder(V holder, int position);
}
子类使用实例方法
public class RvTestAdapter extends RvBaseAdapter<AdapterBean,RvTestAdapter.ViewHolder> {//要传入两个泛型进去
public RvTestAdapter(List<AdapterBean> data, Context context) {
super(data, context);
}
@Override
protected int getLayout(int viewType) { //获得布局文件
return R.layout.rv_adapter;
}
@Override
protected ViewHolder onCreateViewHolder(View convertView) {//创建一个onCreateViewHolder
return new ViewHolder(convertView);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {//绑定onBindViewHolder
holder.mT1.setText(data.get(position).getName());//绑定数据和控件之间
ImageLoader.getInstance().displayCircleImage(context,R.mipmap.ic_launcher,holder.mI1);
...
}
static class ViewHolder extends RecyclerView.ViewHolder {//用插件快速生成的ViewHolder ,这样很方便
@BindView(R.id.T_1)
TextView mT1;
@BindView(R.id.I_1)
ImageView mI1;
ViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
-
第二种情况不用写ViewHolder
封装的父类RvBaseAdapter,里面封住了一个ViewHolder,动态查找控件
public abstract class RvAdapter<T> extends RecyclerView.Adapter<RvAdapter.ViewHolder> {
public List<T> data;
public Context context;
public RvAdapter(List<T> data, Context context) {
this.data = data;
this.context = context;
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(getLayout(viewType), null);
ViewHolder holder = new ViewHolder(itemView, context);
return holder;
}
/**
* 获得布局文件
*
* @return
*/
protected abstract int getLayout(int viewType);
public class ViewHolder extends RecyclerView.ViewHolder {
private HashMap<Integer, View> views;
private Context context;
public ViewHolder(View itemView, Context context) {
super(itemView);
this.views = new HashMap<>();//保存View的map
this.context = context;
}
public <T extends View> T findById(int id) { //查找控件
View view = views.get(id);
if (view == null) {
view = itemView.findViewById(id);
views.put(id, view);
}
return (T) view;
}
public RvAdapter.ViewHolder setText(int id, String txt) {//封装常用的设置数据方法
TextView tv = findById(id);
tv.setText(txt);
return this;
}
public RvAdapter.ViewHolder setOnClickListener(int id, View.OnClickListener listener) {//设置监听
View view = findById(id);
view.setOnClickListener(listener);
return this;
}
public RvAdapter.ViewHolder setImage(int id, String url) {
ImageView img = findById(id);
ImageLoader.getInstance().displayCircleImage(context, url, img);
return this;
}
···//这里可以扩展添加常用的方法
public View getItemView() {
return itemView;
}
}
}
子类使用实例方法
看起来是不是很简洁,窃喜~
public class RvTestAdapter extends RvAdapter<AdapterBean> {
public RvTestAdapter(List<AdapterBean> data, Context context) {
super(data, context);
}
@Override
protected int getLayout(int viewType) {
return R.layout.rv_adapter;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.setText(R.id.T_1, data.get(position).getName())
.setText(R.id.T_1, data.get(position).getName())
.setImage(R.id.I_1, data.get(position).getName())
.setImage(R.id.I_1, data.get(position).getName())
.setOnClickListener(R.id.T_2, new View.OnClickListener() {
@Override
public void onClick(View v) {
App.getInstance().showToast(data.get(position).getName());
}
});
}
}
结语:封装之后代码量显著减少,看上去很简洁
其实还可以在里面添加扩展功能 ==》
public void remove(int position) {
data.remove(position);
notifyItemRemoved(position);
}
public void add(int position, T item) {
data.add(position, item);
notifyItemInserted(position);
}