在查看RecyclerView的官方文档的时候发现了这个recyclerview-selection库,通过测试感受功能挺好的,省去了本身须要编写大量多选功能的代码,官方文档的guide又不是太清晰,这篇文章仅仅做为简单的记录。html
参考:java
根据官方文档的描述,这个库就是用来处理RecyclerView的Item的选择问题,而且能够在设备配置改变的时候保存已选择的数据,从新建立页面的时候再次加载,省去了咱们本身对这部分的操做;同时经过观察者模式提供了item点击监听、长按订阅功能。 android
public class StringItemKeyProvider extends ItemKeyProvider<String> {
private List<String> items;
public StringItemKeyProvider(int scope, List<String> items) {
super(scope);
this.items = items;
}
@Nullable
@Override
public String getKey(int position) {
return items.get(position);
}
@Override
public int getPosition(@NonNull String key) {
return items.indexOf(key);
}
}
复制代码
ItemDetails getItemDetails(@NonNull MotionEvent e)
方法,经过ReyclerView的findChildView(int,int)
方法来判断具体touch的是哪个Item,强转成咱们的ViewHolder类型,调用咱们RecyclerView.ViewHolder中的方法来返回一个ItemDetails实例,返回实例的方法是咱们本身添加的,ViewHolder中并无该抽象方法;public class StringItemDetailsLookup extends ItemDetailsLookup {
private final RecyclerView mRecyclerView;
StringItemDetailsLookup(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
@Nullable
@Override
public ItemDetails getItemDetails(@NonNull MotionEvent e) {
View view = mRecyclerView.findChildViewUnder(e.getX(), e.getY());
if (view != null) {
RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(view);
if (holder instanceof StringItemRecyclerViewAdapter.ItemViewHolder) {
return ((StringItemRecyclerViewAdapter.ItemViewHolder) holder).getItemDetails();
}
}
return null;
}
}
复制代码
如下是返回ItemDetails实例的方法,其中注释的语句是经过继承ItemDetails的子类来建立的。git
ItemDetailsLookup.ItemDetails getItemDetails() {
// return new StringItemDetail(getAdapterPosition(),datas.get(getAdapterPosition()));
return new ItemDetailsLookup.ItemDetails() {
@Override
public int getPosition() {
return getAdapterPosition();
}
@Nullable
@Override
public Object getSelectionKey() {
return datas.get(getAdapterPosition());
}
};
}
复制代码
public class StringItemDetails extends ItemDetailsLookup.ItemDetails {
private int position;
private String item;
public StringItemDetails(int position, String item) {
this.position = position;
this.item = item;
}
@Override
public int getPosition() {
return position;
}
@Nullable
@Override
public Object getSelectionKey() {
return item;
}
}
复制代码
如今咱们准备好了StringItemDetailsLookup
、StringItemKeyProvider
两个类,可是准备好了又怎么用呢?github
android:persistableMode
属性才会调用,一样onSaveInstanceState
、onRestoreInstanceState
也是如此,mAdapter = new StringItemRecyclerViewAdapter(ITEMS);
mRecyclerView.setAdapter(mAdapter);
mSelectionTracker = new SelectionTracker.Builder<>(
"string-items-selection",
mRecyclerView,
new StringItemKeyProvider(1, ITEMS),
new StringItemDetailsLookup(mRecyclerView),
StorageStrategy.createStringStorage())
//设置可选择的item,这里设置为均可选
.withSelectionPredicate(SelectionPredicates.<String>createSelectAnything())
.build();
mAdapter.setSelectionTracker(mSelectionTracker);
复制代码
注意上边setSelectionTracker
方法,这个方法是咱们在自定义的RecyclerView.Adapter中添加的,目的是将咱们建立的SelectionTracker注入到咱们的Adpter。bash
public void setSelectionTracker(SelectionTracker mSelectionTracker) {
this.mSelectionTracker = mSelectionTracker;
}
复制代码
前边说了,咱们在Adapter中添加了getItemDetails
方法,如今咱们的基本工做已经完成,程序能正常运行了,可是咱们还看不到多选的效果,由于tracker并不能为咱们提供选中高亮功能,高亮功能按咱们喜欢的方式实现便可,判断是否选中的代码以下(在Adapter的onBindViewHolder方法中):ide
if (mTracker.isSelected(datas.get(i))) {
viewHolder.tvInfo.setBackgroundColor(Color.parseColor("#80deea"));
} else {
viewHolder.tvInfo.setBackgroundColor(Color.WHITE);
}
复制代码
onSaveInstanceState
、onRestoreInstanceState
中分别调用tracker的onSaveInstanceState
、onRestoreInstanceState
方法便可,以下:@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
mSelectionTracker.onRestoreInstanceState(savedInstanceState);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mSelectionTracker.onSaveInstanceState(outState);
}
复制代码
咱们能够为tracker添加订阅事件或者item单击事件,这样选择状态改变或者item被点击是咱们能够添加本身的逻辑,后续多选操做及多选信息咱们均可以经过tracker的事件或者方法得到,具体请看参考3的代码或者查看官网SelectionTracker的说明。测试
最后,必须第一步的操做,Android studio 3.4居然没法直接搜索recyclerview添加其依赖,搜索结果是androidx版本的,会有冲突,recyclerview-selection却是能够直接搜索依赖到项目中。ui
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:recyclerview-selection:28.0.0'
复制代码