汇报一下上周五阿里双11的战报,销售总额创历史新高,达到了1207亿元,这也是阿里双11单天销售额首次突破1000亿。2014年的数字是572亿元,2015年的数字是912亿元。照这个发展速度来算的话,明年阿里双11单天销售额将有可能突破1500亿。这是不是说明中国人越来越有钱了呢?
大家好,新的一周又开始了!本篇是
张旭童
的第三篇投稿,熟悉的朋友肯定知道,他的前两篇分享了RecyclerView的头部悬停与右侧索引,今天将带来他对单选列表的细致思考,希望大家喜欢。
张旭童
的博客地址:
http://blog.csdn.net/zxt0601
这篇文章需求来源还是比较简单的,但做的
优雅
仍有值得挖掘的地方。
需求来源:一个类似饿了么这种
电商优惠券
的选择界面,其实就是 一个普通的列表,实现了
单选
功能。
效果如图:
不要怪图渣了,我撸了四五遍,公司录出来的GIF就这么渣。。。
常规方法:
在 Javabean 里增加一个 boolean isSelected 字段,并在Adapter里根据这个字段的值设置“CheckBox”的选中状态。
在每次选中一个新优惠券时,改变数据源里的isSelected字段,并notifyDataSetChanged()刷新整个列表。
这样实现起来很简单,代码量也很少,唯一不足的地方就是性能有损耗,不是最优雅。
So作为一个有追求(比较闲)的程序员,我决心分享一波优雅方案。
本文会列举分析一下在ListView和RecyclerView中, 列表实现单选的几种方案,并推荐采用定向刷新 部分绑定的方案,因为更
高效and优雅
。
RecyclerView是我的最爱 ,所以我先说它。
一、常规方案
常规方案 请光速阅读,直接上码,Bean结构:
我项目里有好多单选需求,懒得写isSelected字段,所以弄了个父类供子类继承。
Acitivity 和 Adapter 其他方法都是最普通的不再赘述。
Adapter 的 onBindViewHolder() 如下:
ViewHolder:
方案优点:
简单粗暴
方案缺点:
其实需要修改的Item只有两项:
-
一个当前处于选中状态的Item->普通状态
-
再将当前手指点击的这个Item->选中状态
但采用普通方案,则会刷新整个一屏可见的Item,重走他们的 getView()/onBindViewHolder()方法。
其实一个屏幕一般最多可见10+个Item,遍历一遍也无伤大雅。
但咱们还是要有追求优雅的心,所以我们继续往下看。
二、利用Rv的notifyItemChanged()定向刷新
本方案可以中速阅读
1.
本方案需要在Adapter里新增一个字段:
//实现单选 方法二,变量保存当前选中的position
private int mSelectedPos = -1;
2.
在设置数据集时(构造函数,setData()方法等:),初始化 mSelectedPos 的值。
//实现单选方法二: 设置数据集时,找到默认选中的pos
for (int i = 0; i mDatas.size(); i++) {
if (mDatas.get(i).isSelected()) {
mSelectedPos = i;
}
}
3.
onClick里代码如下:
本方案由于调用了notifyItemChanged(),所以还会伴有“白光一闪”的动画。
方案优点
本方案,较优雅了,不会重走一屏可见的Item的 getView()/onBindViewHolder()方法,但仍然会重走需要修改的两个Item的 getView()/onBindViewHolder()方法。
方案缺点
我们实际上需要修改的,只是里面“CheckBox”的值,按照在 DiffUtil 一文学习到的姿势,术语应该是“Partial bind “,(安利时间,没听过 DiffUtil 和 Partial bind 的 戳->: