封装一个简单的RecyclerView.Adapter

Google推出控件RecyclerView推出以后。ListView逐渐被RecyclerView取代。

那么RecyclerView 和ListView相比有哪些优点呢?

  1. RecylerView封装了viewholder的回收复用,也就是说RecylerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。

  2. 高度的解耦,扩展性强,针对一个Item的显示RecylerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。

  3. 可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecylerView有其自己默认的实现。

前面讲到RecylerView封装了viewholder的回收复用,在我们使用RecyclerView就会用到RecyclerView.Adapter,而每创建一个adapter就要创建一个RecyclerView.ViewHolder类,实际开发中由于会用到不止一个RecyclerView,不断重复以上步奏使得代码臃肿,实现起来非常费劲。大大的增加了程序员的代码工作量。这显然不是我们想要的。

对Adapter封装进行需求分析

继承RecyclerView.BaseAdapter需要实现3个抽象方法:
    1. onCreateViewHolder   
    2. onBindViewHolder   
    3. getItemCount
需要一个RecyclerView.ViewHolder的实现类       

    其中getItemCount()可以构造方法传入数据List,直接实现。

    而onCreateViewHolder则需要返回一个ViewHolder的对象,而创建ViewHolder对象需要一个子条目的根View。考虑到一个Adapter可能有多个activity用到,而布局可能不同,所以我们在构造方法中传入layoutId用来创建view。

Adapter简单实现

public class SimpleQuickAdapter<B> extends RecyclerView.Adapter<SimpleQuickAdapter.SimpleViewHolder> {
    private int layoutId;
    protected List<B> mData;

    /**
     * @param layoutId 子条目的布局
     * @param list      数据
     */
    public SimpleQuickAdapter(@LayoutRes int layoutId, List<B> list) {
        this.layoutId = layoutId;
        this.mData = list != null ? list : new ArrayList<B>();
    }


    @Override
    public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(SimpleViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return mData.size();
    }
}
public class SimpleViewHolder extends RecyclerView.ViewHolder{
    public SimpleViewHolder(View itemView) {
        super(itemView);
    }
}

我们先创建一个SimpleViewHolder类继承RecyclerView.ViewHolder作为Adapter的泛型,因为数据的类型是不确定的,我们这里也设计为泛型。

构造方法传入layoutId后,我们就可以创建ViewHolder,然后实现onCreateViewHolder方法,考虑到Context参数经常在绑定数据的时候用到,而view又能拿到context,所以我们在实现onCreateViewHolder方法的时候顺便拿到Context对象

 protected Context mContext;
    @Override
    public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        mContext = parent.getContext();
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        View view = layoutInflater.inflate(layoutId, parent, false);
        SimpleViewHolder holder = new SimpleViewHolder(view);
        return holder;
    }

在onBindViewHolder方法中,我们可以进行数据绑定,事件监听。
数据绑定显然要交给子类去处理,我们把类改为抽象类,然后定义抽象方法。事件绑定我们就写一个最常用的字条目点击事件。

   private OnItemClickListener onItemClickListener;

   @Override
    public void onBindViewHolder(final SimpleViewHolder holder, final int position) {
        if (this.onItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickListener.onItemClick(SimpleQuickAdapter.this, holder.itemView, mData.get(position), position);
                }
            });
        }
        convert(holder, position, mData.get(position));
    }

    protected abstract void convert(SimpleViewHolder holder, int position, B b);

    public  interface OnItemClickListener {
        void onItemClick(SimpleQuickAdapter adapter, View itemView, Object b, int position);
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

经过以上分装adapter基本上已经可以用了

但是每次用viewHolder绑定数据时,都要用holder.itemView.findViewById(viewId)找到控件后才能对控件进行操作,这就显得有点繁琐。所以我们有必要对Holder进行简单的封装。

public class SimpleViewHolder extends RecyclerView.ViewHolder {
    public SimpleViewHolder(View itemView) {
        super(itemView);
    }

    public <V extends View>V getView(int viewId){
        return itemView.findViewById(viewId);
    }

    public SimpleViewHolder setText(int viewId, String text) {
        TextView view = getView(viewId);
        view.setText(text);
        return this;
    }
    public SimpleViewHolder setText(@IdRes int viewId, @StringRes int strId) {
        TextView view = getView(viewId);
        view.setText(strId);
        return this;
    }
}

我们可以在这里对图片设置,背景设置,设置是否显示…等常用功能进行封装,原理差不多,就不多写了。
我们每次getView都会去访问itemView.findViewById(viewId),如果对同一控件进行多次操作就没这个必要。我们可以拿个容器去存储用过的view来提升效率。

    private SparseArray<View> views;
    public SimpleViewHolder(View itemView) {
        super(itemView);
        this.views = new SparseArray<>();
    }
    //当集合views中有view时直接返回view,当集合中没有view的时候findViewById获取view,并且把这个view存入集合
    public <V extends View>V getView(int viewId){
        View view = views.get(viewId);
        if (view == null) {
            view = itemView.findViewById(viewId);
            views.put(viewId, view);
        }
        return (V) view;
    }

github传送门

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerView.Adapter一个用于管理 RecyclerView 中数据和视图的基类。它有三个主要的方法:onCreateViewHolder、onBindViewHolder 和 getItemCount。 onCreateViewHolder 方法用于创建 ViewHolder 对象,ViewHolder 对象用于保存 RecyclerView 中的视图。onBindViewHolder 方法用于将数据绑定到 ViewHolder 中的视图上。getItemCount 方法用于返回 RecyclerView 中的数据项数量。 在实现 RecyclerView.Adapter 时,我们需要重写这三个方法,并根据实际需求进行相应的处理。此外,我们还可以添加一些其他的方法,例如添加、删除、更新数据等。 下面是一个简单RecyclerView.Adapter 实现示例: ``` public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<String> mData; public MyAdapter(List<String> data) { mData = data; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { String data = mData.get(position); holder.mTextView.setText(data); } @Override public int getItemCount() { return mData.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public ViewHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(R.id.text_view); } } } ``` 在这个示例中,我们创建了一个 MyAdapter 类,它继承自 RecyclerView.Adapter。在构造函数中,我们传入了一个数据列表 mData。在 onCreateViewHolder 方法中,我们使用 LayoutInflater 创建了一个视图,并将其封装在 ViewHolder 中返回。在 onBindViewHolder 方法中,我们将数据绑定到 ViewHolder 中的视图上。在 getItemCount 方法中,我们返回 mData 的大小。 这是一个简单RecyclerView.Adapter 实现示例,实际应用中可能需要更复杂的处理逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值