emmmmmmm第一次写博客,也不知道咋写=。=,写的不好请见谅!最近项目里用到了列表的全选与单选功能(类似于商城购物车),因为之前没有写过,所以等于自己从零学了这个实现的方法(虽然过程是够费劲的。。。),想把这个过程分享给和我一样遇到类似问题的同学,让大家一起进步,大神就一笑带过吧,哈哈哈。。。。首先说一下我的实现思路吧,我是用的RecyclerView做列表,BaseRecyclerViewAdapterHelper作为Adapter库(个人觉得这个库特别好用~)RXJava作为列表与界面交互的介质
下面就开始贴代码啦!
/**
* 初始化RecyclerView
*/
private void initRecyclerView() {
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
/**
* 初始化Adapter
*/
private void initRecyclerViewAdapter() {
recyclerViewAdapter = new RecyclerViewAdapter(this, recyclerViewModeList);
recyclerView.setAdapter(recyclerViewAdapter);
}
/**
* 初始化数据
*/
private void initData() {
for (int i = 1; i <= 16; i++) {
RecyclerViewMode recyclerViewMode = new RecyclerViewMode();
recyclerViewMode.No = String.valueOf(i);
recyclerViewMode.name = i + "只绵羊";
recyclerViewMode.picUrl = "https://imgsa.baidu.com/forum/w%3D580%3B/sign=ca6fd4239a2397ddd679980c69b9b3b7/fcfaaf51f3deb48f23034c1afb1f3a292cf57888.jpg";
recyclerViewModeList.add(recyclerViewMode);
}
}
首先这里是数据以及控件的初始化操作,没啥说的~,接下来是Adapter。选中的状态我个人推荐是用两张图片,然后做图片的点击事件操作,而不是去用CheckBox,因为用CheckBox的setOnCheckedChangeListener()方法在这里使用时不能准确展示我们所需要的状态(不知道这么说对不对,但确实是有问题的)
helper.getView(R.id.imageView_selected).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (item.isCheck) {
item.isCheck = false;
helper.setImageResource(R.id.imageView_selected, R.mipmap.icon_circle_gray);
} else {
item.isCheck = true;
helper.setImageResource(R.id.imageView_selected, R.mipmap.icon_circle_yellow);
}
顺带说一句,item.isCheck是自己在自定义数据模型中定义的boolean值属性,用来在item中判断是否被点击,然后根据状态切换显示的图片
if (item.isCheck) {
helper.setImageResource(R.id.imageView_selected, R.mipmap.icon_circle_yellow);
} else {
helper.setImageResource(R.id.imageView_selected, R.mipmap.icon_circle_gray);
}
这时候就要用到RXJava了,在点击事件监听中加入被观察者
Observable<RecyclerViewMode> observable = Observable.create(new Observable.OnSubscribe<RecyclerViewMode>() {
@Override
public void call(Subscriber<? super RecyclerViewMode> subscriber) {
subscriber.onNext(item);
subscriber.onCompleted();
}
});
observable.subscribe(mainActivity.observer);
}
});
向外部(主界面)发送你所需要的数据,我这里是直接把数据模型发送过去了。然后回到主界面。
敲黑板!!!这里是重点啊同学们!!!
我们队主页面的全选按钮做点击事件监听,并且让点击状态为true的时候循环整个adapter并将数据isCheck设为true,反之亦然
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isSelected) {
isSelected = false;
imageView.setImageResource(R.mipmap.icon_circle_gray);
for (int i = 0; i < recyclerViewAdapter.getData().size(); i++) {
if (recyclerViewAdapter.getData().get(i).isCheck) {
recyclerViewAdapter.getData().get(i).isCheck = false;
}
recyclerViewMap.remove(recyclerViewAdapter.getData().get(i).No);
}
} else {
isSelected = true;
imageView.setImageResource(R.mipmap.icon_circle_yellow);
for (int i = 0; i < recyclerViewAdapter.getData().size(); i++) {
if (!recyclerViewAdapter.getData().get(i).isCheck) {
recyclerViewAdapter.getData().get(i).isCheck = true;
}
recyclerViewMap.put(recyclerViewAdapter.getData().get(i).No, recyclerViewAdapter.getData().get(i));
}
}
recyclerViewAdapter.notifyDataSetChanged();
}
});
这里我们又用了一个Map去保存一下数据中的一个唯一值(这里是No),Map的作用是用来保存当前你选了哪些(或者多少)项Item,后面会用到。还要记得在这里改变完状态后一定要调用notifyDataSetChanged()这个方法,否则就会出现列表滑动后一切就都回到解放前了~
最后还记得我们在Adapter里写的被观察者吧,那么现在我们就在界面上用观察者接受它吧!
observer = new Observer<RecyclerViewMode>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(RecyclerViewMode recyclerViewMode) {
for (int i = 0; i < recyclerViewAdapter.getData().size(); i++) {
if (recyclerViewAdapter.getData().get(i).isCheck) {
recyclerViewMap.put(recyclerViewAdapter.getData().get(i).No, recyclerViewAdapter.getData().get(i));
} else {
recyclerViewMap.remove(recyclerViewAdapter.getData().get(i).No);
}
}
if (recyclerViewMap.size() == recyclerViewAdapter.getData().size()) {
isSelected = true;
imageView.setImageResource(R.mipmap.icon_circle_yellow);
} else {
isSelected = false;
imageView.setImageResource(R.mipmap.icon_circle_gray);
}
}
};
还是用for循环整个adapter用isCheck的状态来判断是该往Map中添加呢还是移出呢,最后我们用Map的Size与Adapter的Size做比较,来判断主页面的全选与非全选状态。
到这里,这个RecyclerView的全选与非全选的基本功能就已经完成了,如果需要用到数据里的值就还是根据isCheck来取值或者移出。还有两点需要注意的就是,注意做Map的clear与非空判断,避免出现重复数据。
这里是我的GitHub地址
这里附上我所用的第三方库
// RecyclerView和Adapter compile 'com.android.support:recyclerview-v7:25.3.1' compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30' // RXJava compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxandroid:1.0.1'