RecyclerView+多ItemType实现两级评论页面
多ItemType实现多级评论页面
前言
我的上一篇文章 Android简单的两级评论功能实现,得到了很多的评论(万万没想到),收获了jym们宝贵的建议和指导,在此特别感谢大家。
在上一篇文章中,对于‘两级评论功能’的实现,我采用的是Recycler嵌套的方法,这种方法的实现不难,但是非常的麻烦,有很多不必要的操作,扩展性很差,维护起来也是十分复杂。虽然最后实现效果还可以,但是有更好更方便的方法,何乐而不为呢。所以这篇文章的内容就是对多ItemType实现评论功能的过程阐述,还有两种实现方式的区别和性能差异。
注:文章要参加更文活动,只会粘贴关键的代码。如需详细代码,请私信。
一、适配器
重复的部分就不说了,数据库和布局部分基本和上一篇是一致的,只是把item布局中的RecyclerView和对应的适配器及相关代码去掉了。
1、创建两个ViewHolder
分别是TestOneViewHolder和TestTwoViewHolder,这里不贴代码只展示布局了
一级评论的布局:
二级评论的布局:
2、设置两个ItemType
LEVEL_ONE_VIEW
是一级评论的ViewType,LEVEL_TWO_VIEW
是二级评论的ViewType
private val LEVEL_ONE_VIEW = 0 // 一级布局的的ViewType
private val LEVEL_TWO_VIEW = 1 // 二级布局的的ViewType
3、方法重写
- 在
getItemViewType
方法中返回ViewType
override fun getItemViewType(position: Int): Int {
val commentInfo = list.toList()[position].first
return if (commentInfo.level == 1) {
LEVEL_ONE_VIEW
} else {
LEVEL_TWO_VIEW
}
}
这里list的类型是‘Map<CommentInfo, User>’,是因为还需要User的数据,所以映射来的。
获取到评论信息后对level进行判断,返回相应的ViewType。
- 在
onCreateViewHolder
中根据ViewType进行判断,根据TYPE返回相应的ViewHolder
override fun onCreateViewHolder(parent: ViewGr0up, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == LEVEL_ONE_VIEW) {
TestOneViewHolder(parent)
} else {
TestTwoViewHolder(parent)
}
}
- 在
onBindViewHolder
通过getItemViewType(position)
来获取当前的ViewType,再进行数据绑定。如图:
4、数据绑定
在ViewHolder中将传入的数据对布局进行赋值就好了,最后实现的效果如下图。为了能够更加直观的看出一级评论与二级评论之间的关联,图片中的评论内容用数字进行标识。
可以看到在设置完多ItemType后,显示的布局符合我们的预期了,可是一级评论和二级评论之间毫无关联,各过各的,那如何将评论布局展示出绑定的效果呢?主要还是对数据进行处理啦,如何处理呢,请看下一节。
二、绑定
这个绑定指的是将与一级评论相关联的二级评论和该一级评论展示在一起,有一种类似的绑定效果。大致思路如下:
- 获取该文章的所有评论
- 分别获取到level为1、2的评论列表
- 将level为2的列表按照回复评论的Id进行分组
- 创建空列表
- 遍历level为1的列表,获取到相应的level2的列表并依次添加进空列表
实现代码如下:
// 获取该文章的所有评论
val comments = commentStoreRepository.getCommentsByNewId(newsId)
// 获取level为1、2的评论、按时间进行排序
val level1 = comments.filter { it.level == 1 }.sortedBy { it.time }
val level2 = comments.filter { it.level == 2 }.sortedBy { it.time }
// 将level为2的列表按照回复评论的Id进行分组
val level2Gr0up = level2.groupBy { it.replyId }
// 创建空列表
val list = mutableListOf<CommentInfo>()
// 遍历level1的列表 获取到对应的level2列表 依次添加进空列表中
level1.forEach { level1Info ->
val newLevel2Gr0up = level2Gr0up[level1Info.id]
list.add(level1Info)
if (newLevel2Gr0up != null) {
list.addAll(newLevel2Gr0up)
}
}
这个空列表,即
list
就是我们需要的能展示强绑定关系的列表啦
最终呈现的效果如下图:
这样,一个多ItemType的二级评论展示就实现啦!!!
三、两种实现方式比对
- 实现1 - 嵌套RecyclerView的实现
- 实现2 - 多ItemView的实现
1、复杂程度:
主观方面来说,
- 实现1 -- 首先是在数据及布局的处理方面,会显得非常杂乱。我在非常了解其数据结构的情况下,很多时候也摸不着头脑,而且代码不方便管理。再就是扩展性,如果在这个实现的基础上进行扩展会非常的复杂,想着要是做个更多层级的评论那得多麻烦。优点就是能够对二级评论进行单独的管理。
- 实现2 -- 单独对布局进行管理,很方便,复杂程度低,扩展性也更好,用来做个多级评论不成问题。缺点:我想实现一个评论下的二级评论最多展示两条,可以展开,还可以显示回复条数的功能不知道怎么做,实现一因为可以对二级数据统一管理就会比较好实现。这一点,如果有大佬知道如何解决,请在评论下激情发表你的言论。
2、性能方面:
分别插入100、1000、10000条数据,记录消耗时间。如图所示,统计的次数较少,但也可以看出二者在性能方面的差异不大。
结论:两种实现性能差异较小。
四、结语
以上,就是多个ItemType实现二级评论的过程和结果以及两种实现方式的主观对比。文章若出现错误,欢迎各位批评指正,写文不易,转载请注明出处谢谢。
来源:juejin.cn/post/7273685263841853496