RecyclerView基礎(一)Adapter與Holder的封裝之RvAdapter,RvHolder

wustor發表於2019-02-25
  • 使用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);
    }
}複製程式碼

總結

  1. 搞Android開發,java基礎的確很重要,封裝,繼承,多型這些如果能夠靈活運用可以讓開發高效很多。
  2. 不能以戰術上的勤奮代理戰略上的懶惰,規劃好了往往能事半功倍。
  3. 任何事情都是小馬過河,去做了,才發現沒有那麼難,也沒有那麼簡單。

Demo下載

相關文章