- 使用Recyclerview已經有一段時間了,打算把自己專案中用到的知識點寫成一個系列,作為自己技術成長的一個記錄,今天簡單寫一下Adapter與Holder的封裝。
如果我想實現一張如下的列表
封裝之前的程式碼
- NormalAdapter的程式碼
public class NormalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<String> mList;
private RvListener mRvListener;
private Context mContext;
private LayoutInflater mLayoutInflater;
public NormalAdapter(List<String> list, Context context, RvListener rvListener) {
mList = list;
mRvListener = rvListener;
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.item_demo, parent, false);
return new NormalHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((NormalHolder) holder).tvDemo.setText(mList.get(position));
}
@Override
public int getItemCount() {
return mList == null ? 0 : mList.size();
}
private class NormalHolder extends RecyclerView.ViewHolder {
private TextView tvDemo;
NormalHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRvListener.onItemClick(v.getId(), getAdapterPosition());
}
});
tvDemo = (TextView) itemView.findViewById(R.id.tv_demo);
}
}
}複製程式碼
程式碼優化
- 物件複用:Adapter中的List,RvListener,Context,LayoutInflater都可以抽取到一個父類裡面,List可以用泛型進行限定
- 監聽事件:Holer中的點選事件是每個Recyclerview都需要的,可以進行抽取Holder到父類,實現Holder的解耦
- 分離Holder:holder裡面主要是進行View的初始化操作以及資料的繫結,抽取出來之後邏輯更加清晰
重構後的程式碼
- RvAdapter
public abstract class RvAdapter<T> extends RecyclerView.Adapter<RvHolder> {
protected List<T> list;
protected Context mContext;
protected RvListener listener;
protected LayoutInflater mInflater;
public RvAdapter(Context context, List<T> list, RvListener listener) {
mContext = context;
mInflater = LayoutInflater.from(context);
this.list = list;
this.listener = listener;
}
@Override
public RvHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return getHolder(parent, viewType);
}
@Override
public void onBindViewHolder(RvHolder holder, int position) {
holder.bindHolder(list.get(position), position);
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public int getItemViewType(int position) {
return 0;
}
protected abstract RvHolder getHolder(ViewGroup parent, int viewType);
}複製程式碼
- RvHolder
public abstract class RvHolder<T> extends RecyclerView.ViewHolder {
private RvListener mListener;
public RvHolder(View itemView, int type, RvListener listener) {
super(itemView);
this.mListener = listener;
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemClick(v.getId(), getAdapterPosition());
}
});
}
public abstract void bindHolder(T t, int position);
}複製程式碼
- NormalAdapter
public class NormalAdapter extends RvAdapter<String> {
public NormalAdapter(Context context, List<String> list, RvListener listener) {
super(context, list, listener);
}
@Override
protected RvHolder getHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.item_demo, parent, false);
return new NormalHolder(view, viewType, listener);
}
}複製程式碼
- NormalHolder
public class NormalHolder extends RvHolder<String> {
private TextView tvDemo;
public NormalHolder(View itemView, int type, RvListener listener) {
super(itemView, type, listener);
tvDemo = (TextView) itemView.findViewById(R.id.tv_demo);
}
@Override
public void bindHolder(String s, int position) {
tvDemo.setText(s);
}
}複製程式碼
總結
- 搞Android開發,java基礎的確很重要,封裝,繼承,多型這些如果能夠靈活運用可以讓開發高效很多。
- 不能以戰術上的勤奮代理戰略上的懶惰,規劃好了往往能事半功倍。
- 任何事情都是小馬過河,去做了,才發現沒有那麼難,也沒有那麼簡單。