带修改-Demo

RecyclerView实现多选

2016-05-18  本文已影响4642人  在巨人的肩膀上努力奔跑

最近在做项目时遇到一个小功能,实现多选的功能。刚拿到时首先想到的是看能不能直接在Adapter中设置item的选中状态,简单查了下API发现没有这样的函数供我们使用。google了下,在GitHub上找到了drag-select-recyclerview可以轻松实现RecyclerView的多选。

期望的效果图
如何使用

drag-select-recyclerview的使用还是非常简单的,我们添加依赖后发现drag-select-recyclerview内容非常简单,主要由DragSelectRecyclerView与DragSelectRecyclerViewAdapter组成,这两个类共同协作提供了我们想要的功能。

目录结构
DragSelectRecyclerView

DragSelectRecyclerView继承了RecyclerView且在布局文件中取代了RecyclerView,所以,你需要在xml中引入该组件。

<com.afollestad.dragselectrecyclerview.DragSelectRecyclerView
        android:id="@+id/base_info_recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
</com.afollestad.dragselectrecyclerview.DragSelectRecyclerView>

与RecyclerView一样,同时你也需要设置LayoutManager与Adapter

mRecycler.setLayoutManager(new GridLayoutManager(mContext,3));
mRecycler.setAdapter(mAdapter);

不同的是,此时的Adapter必须为DragSelectRecyclerViewAdapter的子类。

DragSelectRecyclerViewAdapter

在Adapter中关键点在于通过isIndexSelected方法来判断item是否被选择。

@Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        super.onBindViewHolder(holder, position);
        if(isIndexSelected(position)){//item是否选择
            holder.mImg.setImageResource(R.mipmap.match_item_city_icon);
        }else{
            holder.mImg.setImageResource(R.mipmap.icon_match_item_img);
        }
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                callBack.onBaseInfoItemClick(position);
            }
        });
    }
Activity调用

在Adapter Item回调方法中只需调用toggleSelected(index)来切换选择

@Override
    public void onBaseInfoItemClick(int index) {
        mAdapter.toggleSelected(index);
    }

仅仅调用这一个方法就可以轻松实现多选?通过查询此方法的内部实现可以看到:通过传递的index进行判断,如果在选中列表中就将它移除,反之添加到选中列表中,随后通知适配器刷新。在之前适配器中检查item是否被选中也是通过这样一个逻辑来判断的。其内部实现逻辑还是蛮简单易于理解的。

public final boolean toggleSelected(int index) {
        boolean selectedNow = false;
        if (isIndexSelectable(index)) {
            if (mSelectedIndices.contains(index)) {
                mSelectedIndices.remove((Integer) index);
            } else if (mMaxSelectionCount == -1 ||
                    mSelectedIndices.size() < mMaxSelectionCount) {
                mSelectedIndices.add(index);
                selectedNow = true;
            }
            notifyItemChanged(index);
        }
        fireSelectionListener();
        return selectedNow;
    }

通过源码发现DragSelectRecyclerViewAdapter也提供了许多可选方法供我们使用,顾名思义,大多数外部调用的方法也比较容易理解。更多用法还需仔细研读源码...

DragSelectRecyclerViewAdapter目录结构
上一篇下一篇

猜你喜欢

热点阅读