Android万能适配器BaseListAdapter

        我们在写列表的时候都要用到适配器Adapter,如果每一个列表都去创建一个Adapter以及相应的ViewHolder,则重复代码太多,效率低下,为了改变这种情况,我们需要做到尽可能多的复用Adapter以及ViewHolder,我们称之为万能适配器。网上也有各种各样实现的万能适配器,本文将给出一种万能适配器实现方案。

        在自定义Adapter时,都需要继承系统的适配器RecyclerView.Adapter,以及系统的RecyclerView.ViewHolder。以下是定义的万能适配器代码:

public abstract class BaseListAdapter<T ,VH extends BaseListViewHolder> extends RecyclerView.Adapter<VH> {
    private List<T> datas;

    public void setDatas(List<T> datas) {
        this.datas = datas;
    }

    public List<T> getDatas() {
        if (null == datas) {
            return new ArrayList<>();
        }
        return datas;
    }

    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return onCreateMyViewHolder(parent,viewType);
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        onBindMyViewHolder(holder,position);
    }

    public abstract VH onCreateMyViewHolder(ViewGroup parent,int viewType);

    public abstract void onBindMyViewHolder(VH holder , int position);

    @Override
    public int getItemCount() {
        return datas.size();
    }
}

范型T是定义的数据类型,VH可以自定义的ViewHolder,但是必须要继承自BaseListViewHolder,当然VH也可以是BaseListViewHolder,BaseListViewHolder是继承自系统ViewHolder的,后面会给出实现方式。代码中定义了两个抽象方法

public abstract VH onCreateMyViewHolder(ViewGroup parent,int viewType)、public abstract void onBindMyViewHolder(VH holder , int position),VH都是我们可以自定义的ViewHolder,onCreateMyViewHolder创建VH,由系统方法onCreateViewHolder调用;onBindMyViewHolder绑定数据并渲染UI,由系统onBindViewHolder调用。

        BaseListViewHolder实现如下:

public class BaseListViewHolder extends RecyclerView.ViewHolder {
    // 缓存子View,减少findViewById的次数
    private SparseArray<View> mViews;
    public BaseListViewHolder(@NonNull View itemView) {
        super(itemView);
        mViews = new SparseArray<>();
    }

    public <V extends View> V getView(int viewId){
        View view = mViews.get(viewId);
        if (null==view){
            view = itemView.findViewById(viewId);
            mViews.put(viewId,view);
        }
        return (V)view;
    }
}

SparseArray<View> mViews用来缓存View,当viewId相同时就直接从parseArray<View> mViews取出,避免重复findViewById,提高列表性能。

      BaseListAdapter的使用示例如下:

public class TestActivity extends Activity {
    private BaseListAdapter<DataClass, BaseListViewHolder> mAdapter;
    private RecyclerView mRecyclerView;
    private List<DataClass> datas;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mRecyclerView = new RecyclerView(this);
        setContentView(mRecyclerView);
        initData();
        initView();
    }

    private void initData(){
        datas = new ArrayList<>();
        for (int i=0;i<2;i++){
            DataClass data = new DataClass();
            data.setType(i);
            data.setData("data"+i);
            datas.add(data);
        }
    }

    private void initView(){
        mAdapter = new BaseListAdapter<DataClass, BaseListViewHolder>() {
            @Override
            public int getItemViewType(int position) {
                return getDatas().get(position).getType();
            }

            @Override
            public BaseListViewHolder onCreateMyViewHolder(ViewGroup parent, int viewType) {
                View view;
                if (viewType == 0){
                    view = LayoutInflater.from(TestActivity.this).inflate(R.layout.layout1, parent, false);
                }else {
                    view = LayoutInflater.from(TestActivity.this).inflate(R.layout.layout2, parent, false);
                }

                return new BaseListViewHolder(view);
            }

            @Override
            public void onBindMyViewHolder(BaseListViewHolder holder, int position) {
                TextView textView;
                if (getDatas().get(position).getType() == 0){
                    textView = holder.getView(R.id.textView1);
                }else {
                    textView = holder.getView(R.id.textView2);
                }
                textView.setText(getDatas().get(position).getData());

            }
        };
        mAdapter.setDatas(datas);
        mRecyclerView.setAdapter(mAdapter);
    }


    public class DataClass{
        private int type;

        private String data;

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public String getData() {
            return null == data ? "" : data;
        }

        public void setData(String data) {
            this.data = data;
        }
    }
}

示例代码中layout1和layout2都只是放了一个TextView的xml文件,很简单,所以就不给出xml文件了,示例代码很简单,就不做分析了。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值