×

8.使用BaseRecyclerViewAdapter来简化使用

96
Pich
2017.04.04 21:52 字数 488
/**
 * 作者: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效果。并提供必要的封装。

完整版代码,已被不时之需。请查看原文有字数限制。

RecyclerView
Web note ad 1