简介
现在越来越多的电商app都参照了京东和天猫风格的商品列表,商品列表页有一个侧滑筛选菜单,我们产品也不例外,在网上看大部分都是recyclerview嵌套gridview的方式实现的,这样会在一些低配的手机上运行非常卡顿,如果筛选项过多甚至会有一些不可预估的问题(如快速点击,造成数据索引错乱,直接奔溃),用户体验极差。
使用一个recyclerview实现京东筛选菜单
下面我们就来介绍如何使用一个recyclerview就可以 实现京东的筛选菜单。首先,我们先来看筛选菜单有哪些功能:
单选和多选 ,筛选项的每一个类目都有可能是单选或多选;
展开收起 ,每一个类目如果下面的选项大于6项,那么初始化就显示6项,其余的可点击以及标题进行展开和收起;
展示筛选项 ,用户点击某一筛选项时,在父级标题展示所选筛选项;
重置,点击重置按钮时,重置所有筛选项;
获取筛选项,点击确定按钮时,获取所选项,进行筛选。
screenshot
image
image
实现
说了这么多,我们先来看看是怎么实现的吧!
先来定义我们的筛选数据对象:
/**
* 数据对象
*/
data class FilterDao(
// 一级标题对象
var filterParentDao: FilterParentDao? = null,
// 筛选项集合
var sub: List? = null
) {
data class Sub(
var id: Int? = null,
var name: String? = null,
var desc: String? = null,
var isShow: Boolean = true,
var isCheck: Boolean = false
)
}
data class FilterParentDao(
var id: Int? = null,
var name: String? = null,
var desc: String? = null,
var isShow: Boolean = false
)
接下来创建一个ItemStatus对象,用于管理和计算我们的item状态:
class ItemStatus {
companion object {
// 父标题 itemType
val VIEW_TYPE_GROUP_ITEM = 0
// 子标题 itemtYPE
val VIEW_TYPE_SUB_ITEM = 1
}
var mViewType: Int = -1
var mGroupItemIndex: Int = -1
var mSubItemIndex: Int = -1
}
既然是列表,那么最重要的肯定就是我们的adapter了:
/**
* Created Kevin by on 2018/10/30.
*/
class GoodsFilterAdapter(private val mDataListTrees: MutableList, val mContext: Context) :
RecyclerView.Adapter() {
private var mGroupItemStatus: MutableList = mutableListOf() // 保存一级标题的开关状态
companion object {
// 子列表收起时,最少展示的数量, 默认是6
private const val MIN_COUNT = 6
}
/**
* 设置显示的数据
*
* @param dataListTrees
*/
fun setData(dataListTrees: List) {
this.mDataListTrees.clear()
this.mDataListTrees.addAll(dataListTrees)
initGroupItemStatus()
notifyDataSetChanged()
}
/**
* 初始化一级列表开关状态
*/
private fun initGroupItemStatus() {
mGroupItemStatus = ArrayList()
for (i in mDataListTrees.indices) {
mGroupItemStatus.add(false)
}
}
/**
* 根据item的位置,获取当前Item的状态
*
* @param position 当前item的位置(此position的计数包含groupItem和subItem合计)
* @return 当前Item的状态(此Item可能是groupItem,也可能是SubItem)
*/
private fun getItemStatusByPosition(position: Int