RecyclerView.Adapter相比ListView的Adapter的写法已经相当简洁。但是在使用中实现的方法还是有点多,所以,在借鉴其他大神的写法中,总结一下自认为比较简便RecyclerView.Adapter写法。
0x00:RecyclerView.Adapter 原来的写法
RecyclerView.Adapter常规实现方法相比ListView已经相当精简
实现三个接口,再继承一个RecyclerView.ViewHolder就完成
以下是TestAdapter实现RecyclerView.Adapter的范例
/**
* @author Rock you
*/
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder>{
private List<String> mDataList;
private Context mContext;
public TestAdapter(Context context, List<String> dataList) {
this.mContext = context;
this.mDataList = dataList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.test_item, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Button button = holder.mButton;
button.setText(mDataList.get(position));
}
@Override
public int getItemCount() {
if (mDataList == null){
return 0;
}
return mDataList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
Button mButton;
public MyViewHolder(View itemView) {
super(itemView);
mButton = (Button)itemView.findViewById(R.id.main_item_btn);
}
}
}
如上所述,在写大项目的时候,如果存在有许多Adapter,必然是一个很大的工程量。
所以,为了简化Adapter,所需要实现的接口越少越好。
0x01:RecyclerView.Adapter简化
废话不多说直接上代码
/**
* RecyclerView.Adapter的再封装
* 只需要复写两个abstract方法即可
* Created by Rock you
*/
public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<BaseRecyclerAdapter.BaseViewHolder>{
private Context mContext;
private LayoutInflater mLayoutInflater;
//数据源
protected List<T> mListData;
private BaseRecyclerAdapter.OnItemClickListener mItemClickListener;
/**
* 构造函数
* @param context
*/
public BaseRecyclerAdapter(Context context){
this(context, Collections.<T>emptyList());
}
/**
* 构造函数
* @param context
* @param listData
*/
public BaseRecyclerAdapter(Context context, List<T> listData){
this.mListData = listData;
this.mContext = context;
this.mLayoutInflater = LayoutInflater.from(context);
}
/**
* 设置数据源
* @param listData
*/
public void setListData(List<T> listData){
this.mListData = listData;
}
public void setItemClickListener(BaseRecyclerAdapter.OnItemClickListener itemClickListener){
this.mItemClickListener = itemClickListener;
}
/**
* 复写来自RecyclerView.Adapter的
* onCreateViewHolder抽象方法
* @param parent
* @param viewType
* @return
*/
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(getLayoutID(), parent, false);
BaseViewHolder viewHolder = new BaseViewHolder(view);
return viewHolder;
}
/**
* 复写来自RecyclerView.Adapter的
* onBindViewHolder抽象方法
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.setItemClickListener(mItemClickListener, position);
bindHolder(holder, position);
}
/**
* 复写来自RecyclerView.Adapter的
* getItemCount的抽象方法
* @return
*/
@Override
public int getItemCount() {
if (mListData == null){
return 0;
}
return mListData.size();
}
/**
* 返回该itemView的id值
* @return itemView的id
*/
protected abstract int getLayoutID();
/**
* 绑定ViewHolder
* 通过调用holder的getItemView得到任何View
* 或者getImageView得到ImageView
* getTextView得到TextView
* getEditText得到EditText
* 同时在做上述getxxx操作的过程中通过id find各个View
* @param holder
* @param position
*/
protected abstract void bindHolder(BaseViewHolder holder, int position);
/**
* BaseViewHolder类
* 静态类,防止持有外部类的引用,造成内存泄露
* 在bindHolder中调用BaseViewHolder的
* getItemView和getImageView,getTextView,getEditText
*/
static class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(View itemView) {
super(itemView);
}
public void setItemClickListener(
final BaseRecyclerAdapter.OnItemClickListener listener,
final int position){
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null){
listener.onItemClick(itemView, position);
}
}
});
}
/**
* 重要代码
* 利用定义在方法上的泛型
* 方法返回什么类型的View,就绑定什么类型的View
* @param id
* @param <T>
* @return
*/
public <T extends View> T getItemView(int id){
T v = (T)itemView.findViewById(id);
if (v == null){
throw new IllegalArgumentException("itemView's id no exist or error!");
}
return v;
}
public ImageView getImageView(int id){
return getItemView(id);
}
public TextView getTextView(int id){
return getItemView(id);
}
public EditText getEditText(int id){
return getItemView(id);
}
}
/**
* 整个ItemView的回调接口
*/
public interface OnItemClickListener{
void onItemClick(View itemView, int position);
}
}
我将原先的三个接口(‘onCreateViewHolder‘,’onBindViewHolder‘,’getItemCount‘)实现,对外提供’getLayoutID‘和’bindHolder‘接口。由于RecyclerView的没有提供itemView的回调接口,所以在Adapter内部提供一个接口
/**
* 整个ItemView的回调接口
*/
public interface OnItemClickListener{
void onItemClick(View itemView, int position);
}
0x02:BaseRecyclerAdapter的使用
实现BaseRecyclerAdapter实现后的代码只需要实现”getLayoutID“和”bindHolder“即可。
“getLayoutID”返回该RecyclerView的layoutID,”bindHolder”中处理逻辑和绑定View。
View的绑定一句话就可以搞定”Button button = holder.getItemView(R.id.my_id);”,是不是相当简洁。
使用方法:
/**
* Created by Rock You
*/
public class MainAdapter extends BaseRecyclerAdapter<String>{
public MainAdapter(Context context, List<String> listData) {
super(context, listData);
}
// 该Adapter的layout资源
@Override
protected int getLayoutID() {
return R.layout.main_item;
}
// 绑定数据
@Override
protected void bindHolder(BaseViewHolder holder, int position) {
Button button = holder.getItemView(R.id.main_item_btn);
String text = mListData.get(position);
if (!TextUtils.isEmpty(text)){
button.setText(text);
}
}
}
你肯定会纳闷绑定数据是怎么做的?
数据绑定利用java泛型知识来实现,如下代码
public <T extends View> T getItemView(int id){
T v = (T)itemView.findViewById(id);
if (v == null){
throw new IllegalArgumentException("itemView's id no exist or error!");
}
return v;
}
public ImageView getImageView(int id){
return getItemView(id);
}
public TextView getTextView(int id){
return getItemView(id);
}
public EditText getEditText(int id){
return getItemView(id);
}
利用定义在方法上的泛型。
实际上就是,返回值是什么类型,就绑定什么类型。比如返回Button,就绑定Button类型
Button button = holder.getItemView(R.id.main_item_btn);
这样写法有效避免每次写Adapter都需要”findViewById”。达到简化的目的。