BaseRecyclerViewAdapterHelper适配器 github:https://github.com/CymChad/BaseRecyclerViewAdapterHelper
官方教程:
https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki/Expandable-Item
实现功能主要点在三处:
1.实体类配置
2.数据的配置
3.适配器配置
第一步:实体类配置:
1.上一级实体类需要继承AbstractExpandableItem,其中SecondTypeBean是你的下一级列表的实体类,可根据实际情况来写如自己的实体类;
2.每一级实体类都需要实现MultiItemEntity;
3.重写AbstractExpandableItem与MultiItemEntity的方法 getLevel()与getItemType() ,这两个方法的返回值都是列表的类型,每一级实体类用一个数字表示就可以。
//一级列表实体类
data class FirstTypeBean(val name: String) : AbstractExpandableItem<SecondTypeBean>(), MultiItemEntity {
override fun getLevel(): Int {
return 0 //代表 一级列表
}
override fun getItemType(): Int {
return 0 //代表 一级列表
}
}
//二级列表实体类
data class SecondTypeBean(val name: String) : MultiItemEntity {
override fun getItemType(): Int {
return 1 //代表 二级列表
}
}
第二步:数据的配置
先把这个官方demo看明白:
addSubitem是添加下级列表 中的数据
如: lv0.addSubItem(lv1); 这里lv0是一级列表,lv1是二级列表
for (int i = 0; i < lv0Count; i++) {
Level0Item lv0 = new Level0Item(...);
for (int j = 0; j < lv1Count; j++) {
Level1Item lv1 = new Level1Item(...);
for (int k = 0; k < personCount; k++) {
lv1.addSubItem(new Person());
}
lv0.addSubItem(lv1);
}
res.add(lv0);
}
然后看下demo中的数据配置代码:
这里实现了一个MyApi接口,主要是为了解决在activity中利用adapter来设置的点击事件中的position不准确,
现在是一个适配器来控制多级列表,在列表展开后position会变动,暂时我没找到解决办法,只能使用适配器中的点击事件来回掉activity中的方法
class MainActivity : AppCompatActivity(), MyApi {
private var firstList: MutableList<FirstTypeBean>? = ArrayList() // 一级列表内容List
private var secondtList: MutableList<SecondTypeBean>? = ArrayList() // 二级列表内容List
private var allList: MutableList<MultiItemEntity>? = ArrayList() // 全部内容List
private var firstBean: FirstTypeBean? = null //一级列表实体类
private var adapter: MyExpandRecaclerAdapter? = null //树形列表适配器
//一些模拟 数据
private val firstString: Array<String> = arrayOf("法师", "战士", "射手", "坦克", "刺客") // 一级列表数据
private val twoString = arrayOf(
arrayOf("诸葛亮", "王昭君", "司马懿", "小乔", "沈梦溪"),
arrayOf("凯", "曹操", "赵云", "花木兰", "吕布"),
arrayOf("后羿", "公孙离", "成吉思汗", "马可波罗", "李元芳"),
arrayOf("亚瑟", "项羽", "廉颇", "张飞", "程咬金"),
arrayOf("韩信", "百里玄策", "李白", "孙悟空", "阿珂")
) // 二级列表数据 (一个二维数组)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initData() // 初始化数据
setRecycler() // 设置RecyclerView
}
private fun initData() {
for (element in firstString) { //向一级列表List添加数据
val mfirstBean = FirstTypeBean(element)
firstList?.add(mfirstBean)
}
for (a: Int in 0 until firstList!!.size) { // 依次添加一级列表数据
firstBean = FirstTypeBean(firstList!![a].name)
addSecond(a) // 一级列表每个数据下添加相关的 二级数据
allList!!.add(firstBean!!) // 把整合完的数据加入全部列表中
}
}
private fun addSecond(i: Int) {
secondtList?.clear() //每次添加之前不上一次的数据清空避免重复加载
for (element in twoString[i]) { //向二级列表List填加数据
val secondBean = SecondTypeBean(element)
secondtList?.add(secondBean)
}
for (a: Int in 0 until secondtList!!.size) { // 每个一级列表下的二级数据
firstBean?.addSubItem(SecondTypeBean(secondtList!![a].name)) //添加一级列表下的二级列表数据
}
}
private fun setRecycler() { // 设置RecyclerView
recycler.layoutManager = LinearLayoutManager(this)
adapter = MyExpandRecaclerAdapter(allList)
adapter!!.setMyApi(this) // 实现回掉方法
recycler.adapter = adapter
}
override fun first(name: String) { //接口回掉方法
Toast.makeText(this, name, Toast.LENGTH_SHORT).show()
}
override fun second(name: String) { //接口回掉方法
Toast.makeText(this, name, Toast.LENGTH_SHORT).show()
}
}
第三步:适配器配置
这里适配器类继承BaseMultiItemQuickAdapter树形列表适配器,第一个参数是固定的MultiItemEntity
需要在初始化块中进行addItemType,添加多级列表的布局,java中就在构造方法中使用addItemType
class MyExpandRecaclerAdapter(data: MutableList<MultiItemEntity>?) :
BaseMultiItemQuickAdapter<MultiItemEntity, BaseViewHolder>(data) {
private val ITEM_TYPE0 = 0 // 布局类型:一级列表
private val ITEM_TYPE1 = 1 // 布局类型:二级列表
private var api: MyApi? = null // 回掉接口
init {
//有几个布局就加几个addItemType,一参事自定义的常量类型,二参是该列表的item布局
addItemType(ITEM_TYPE0, R.layout.layout_item0)
addItemType(ITEM_TYPE1, R.layout.layout_item1)
}
override fun convert(helper: BaseViewHolder?, item: MultiItemEntity?) {
when (item?.itemType) {
0 -> { // 类型为0是一级列表
val firstBean: FirstTypeBean = item as FirstTypeBean
helper!!.setText(R.id.text_item0, firstBean.name) // 设置一级列表文字
.setImageResource(R.id.arrow_img, if (firstBean.isExpanded) R.drawable.arrow_down else R.drawable.arrow_right) // 设置箭头图标
helper.itemView.setOnClickListener {
val pos: Int = helper.adapterPosition // 获取当前项的下标
if (firstBean.isExpanded) { //判断当前项是否展开
collapse(pos) //展开就关闭
} else {
expand(pos) // 关闭就展开
api!!.first(firstBean.name) //点击回掉activity中的first方法来吐丝
}
}
}
1 -> { // 类型为1是二级列表
val secondBean: SecondTypeBean = item as SecondTypeBean // 强制类型转换
helper!!.setText(R.id.text_item1,secondBean.name)// 设置二级列表的文本
helper.itemView.setOnClickListener {
api!!.first(secondBean.name) //点击回掉activity中的first方法来吐丝
}
}
}
}
fun setMyApi(api: MyApi) { //接收一个实现了MyApi的实例
this.api = api
}
}
简单的效果就实现了,以前没接触过树形列表,所以写下这篇文章记录一下,也方便自己查看,如有写的不好不对的地方,还请帮忙指出!