Android 封装RecyclerView的Adapter

开始之前

有段时间没有写博客了,今天仔细学习了一下封装RecyclerView对Adapter和ViewHolder的封装,所以抓紧时间记录一下

导包之类的基本使用我就不说了,直接进入今天的主题

封装ViewHolder


    /**
     * Created by lulu on 2017/1/22.
     * RecyclerView.ViewHolder 的公共类,做了一些封装。目的:
     * ViewHolder 与 Adapter 解耦,和 ViewHolder 相关的逻辑都放到 ViewHolder 里边,避免 Adapter 有相关逻辑
     */
    public abstract class CommonRecyclerViewHolder<T> extends RecyclerView.ViewHolder {


    public CommonRecyclerViewHolder(Context context, ViewGroup root, int layoutRes) {
        super(LayoutInflater.from(context).inflate(layoutRes, root, false));
    }

    /**
     * 用给定的 data 对 holder 的 view 进行赋值
     */
    public abstract void bindData(T t);

    /**
     * 因为 CommonRecyclerAdapter 里边无法对于未知类型的 Class 进行实例化
     * 所以需要如果想用 CommonRecyclerAdapter,必须要在对应的 CommonViewHolder 实例化一个 HOLDER_CREATOR
     * 注意:public static ViewHolderCreator HOLDER_CREATOR,名字与修饰符都不能更改,否则有可能引发失败
     * 
     * 如果不使用 CommonListAdapter,则不需要实例化 ViewHolderCreator
     *
     * @param <VH>
     */
    public interface ViewHolderCreator<VH extends CommonRecyclerViewHolder> {
        VH createByViewGroupAndType(ViewGroup parent, int viewType);
    }

ViewHolderCreator用于在CommonRecyclerAdapter中创建ViewHolder实例用

封装Adapter


/**
 * Created by lulu on 2017/1/22.
 * 单类型 item 的 RecyclerView 对应的 Adapter
 */

public class CommonRecyclerAdapter<T> extends RecyclerView.Adapter<CommonRecyclerViewHolder> {

    private static HashMap<String, CommonRecyclerViewHolder.ViewHolderCreator> creatorHashMap = new HashMap<>();
    private Class<?> vhClass;
    //数据源
    protected List<T> dataList = new ArrayList<>();

    public CommonRecyclerAdapter() {
        super();
    }

    public CommonRecyclerAdapter(Class<?> vhClass) {
        this.vhClass = vhClass;
    }

    /**
     * 设置数据,会清空之前的数据
     *
     * @param datas
     */
    public void setDataList(List<T> datas) {
        dataList.clear();
        if (datas != null) {
            dataList.addAll(datas);
        }
    }

    /**
     * 添加数据,默认在最后插入,以前数据保留
     *
     * @param datas
     */
    public void addDataList(List<T> datas) {
        dataList.addAll(datas);
    }

    @Override
    public CommonRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (vhClass != null) {
            try {
                //不设置holder直接抛出异常
                throw new IllegalArgumentException("please use CommonListAdapter(Class<VH> vhClass)");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        CommonRecyclerViewHolder.ViewHolderCreator<?> creator = null;
        if (creatorHashMap.containsKey(vhClass.getName())) {
            creator = creatorHashMap.get(vhClass.getName());
        } else {
            try {
                creator = ((CommonRecyclerViewHolder.ViewHolderCreator) vhClass.getField("HOLDER_CREATOR").get(null));
                creatorHashMap.put(vhClass.getName(), creator);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        if (creator != null) {
            return creator.createByViewGroupAndType(parent, viewType);
        } else {
            throw new IllegalArgumentException(vhClass.getName() + " HOLDER_CREATOR should be instantiated");
        }
    }

    @Override
    public void onBindViewHolder(CommonRecyclerViewHolder holder, int position) {
        if (position >= 0 && position < dataList.size()) {
            holder.bindData(dataList.get(position));
        }
    }

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

内部的HashMap防止多次创建ViewHolder
至此封装完毕,接下来做个简单的测试

MyViewHolder.java

/**
 * Created by lulu on 2017/1/22.
 * 测试ViewHolder
 */
public class MyViewHolder extends CommonRecyclerViewHolder<String> {

    private TextView mTextView;

    public MyViewHolder(ViewGroup root) {
        super(root.getContext(), root, android.R.layout.simple_expandable_list_item_1);
        initView();
    }

    private void initView() {
        mTextView = (TextView) itemView.findViewById(android.R.id.text1);
    }

    public static ViewHolderCreator HOLDER_CREATOR = new ViewHolderCreator<MyViewHolder>() {
        @Override
        public MyViewHolder createByViewGroupAndType(ViewGroup parent, int viewType) {
            return new MyViewHolder(parent);
        }
    };

    @Override
    public void bindData(String str) {
        mTextView.setText(str);
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
        CommonRecyclerAdapter<String> adapter = new CommonRecyclerAdapter<>(MyViewHolder.class);
        List<String> mList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            mList.add("测试数据 " + i);
        }
        recycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recycler.setAdapter(adapter);
        adapter.setDataList(mList);
    }
}

截图

这里写图片描述

致谢

参考 LeanCloud中的源码部分
有啥错误还请大神们指出^v^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值