/**
* 作者:Pich
* 原文链接:http://me.woblog.cn/
* QQ群:129961195
* 微信公众号:woblog
* Github:https://github.com/lifengsofts
*/
详解RecyclerView系列文章目录
概述
如果你经常使用RecyclerView,那么你会发现他的使用方法比ListView复杂多了,需要手动设置布局管理器,设置分割线,设置条目动画,还得处理点击事件,长按事件等。那么这节课就是要来解决这些问题,封装一些常用的东西。
添加数据,ViewHolder泛型
public abstract class BaseRecyclerViewAdapter<D,V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V> {
}
可以看到我们给BaseRecyclerViewAdapter添加了两个泛型,D用来标示数据的类型,也就是bindData这个方法中药显示的数据类型,添加他的目的是,我们还要在这个类添加getData这样的方法,这样在需要用数据的时候不需要将Object类型转为自己的类型了,后面的V标示ViewHolder的类型,这样就可以在onCreateViewHolder,onBindViewHolder拿到自己当时定义的类型,免去了强转。
添加数据源容器
我们添加一个容器的好处是,好处就是不会空指针。同时可以在父类实现getItemCount这样的通用方法
private List<D> data = new ArrayList<>();
public void addData(List<D> data) {
this.data.addAll(data);
notifyItemRangeChanged(data.size() - 1, data.size());
}
public void setData(List<D> data) {
this.data.clear();
this.data.addAll(data);
notifyDataSetChanged();
}
public D getData(int position) {
return data.get(position);
}
@Override
public int getItemCount() {
return data.size();
}
@Override
public long getItemId(int position) {
return position;
}
添加了一些常用的方法。方便开发的的时候快速使用。
添加点击事件
定义接口这里就不贴代码了,直接上重要的代码。
@Override
public void onBindViewHolder(final V holder, final int position) {
//点击事件
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener!=null) {
onItemClickListener.onItemClick(holder,position);
}
}
});
}
//常按事件
if (onItemLongClickListener != null) {
holder.itemView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return onItemLongClickListener.onItemLongClick(holder,position);
}
});
}
}
添加所有的ViewHolder的父类
这样做的目的是,所有的ViewHolder都继承自我们的类,这样一来我们就可以在父类使用像butterknife这样的框架。
public abstract class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(View itemView) {
super(itemView);
//TODO 可以在这里加入butterknife这样的框架。
}
@Nullable
public final View findViewById(@IdRes int id) {
return itemView.findViewById(id);
}
}
使用自己的Adapter
public class UseCustomAdapter extends BaseRecyclerViewAdapter<String,UseCustomAdapter.ViewHolder> {
public UseCustomAdapter(Context context) {
super(context);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(getInflater().inflate(android.R.layout.simple_list_item_1,parent,false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
holder.bindData(getData(position));
}
class ViewHolder extends BaseRecyclerViewAdapter.ViewHolder{
private final TextView tv;
public ViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(android.R.id.text1);
}
public void bindData(String data) {
tv.setText(data);
}
}
}
可以看到这次少了很多任务,这个Adapter类也就简化了很多,从而提高开发效率。
RecyclerView rv= (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
UseCustomAdapter useCustomAdapter = new UseCustomAdapter(this);
rv.setAdapter(useCustomAdapter);
ArrayList<String> data = new ArrayList<>();
for (int i = 0; i < 50; i++) {
data.add("Item " + i);
}
useCustomAdapter.setData(data);
下一期讲解如果实现类似ListView的EmptyView效果。并提供必要的封装。
完整版代码,已被不时之需。请查看原文有字数限制。