如何使用Kotlin在Android中实现带层级引导线的RecyclerView列表
Android Kotlin 实现RecyclerView层级引导线方案
你要的层级引导线效果可以通过RecyclerView.ItemDecoration实现,无需修改列表项布局,性能开销更低,具体实现逻辑如下:
实现步骤
- 先给数据实体类新增两个字段:
level: Int:标记当前条目的层级,根节点为0,一级子项为1,二级子项为2,以此类推isLastInGroup: Boolean:标记当前条目是否为所属父分组下的最后一个子项,用于判断纵向引导线的绘制长度
- 自定义类继承
RecyclerView.ItemDecoration,重写两个核心方法:getItemOffsets():给每个列表项设置左侧偏移,偏移宽度为level * 每级缩进宽度,给引导线预留绘制空间,避免引导线覆盖条目内容onDraw():在方法内遍历当前可见的列表项,根据条目层级和分组属性绘制引导线:纵向引导线:每一层级对应固定的X轴坐标,若当前条目在该层级下不属于分组最后一项,竖线从条目顶部画到底部;若为最后一项,竖线仅画到横向引导线对齐的位置
横向引导线:从当前条目层级对应的X轴坐标开始,向右绘制到条目内容的左边缘位置
- 给RecyclerView添加你自定义的ItemDecoration即可生效:
recyclerView.addItemDecoration(YourCustomLevelDecoration())
简化实现示例(核心逻辑)
// 先定义全局的扩展方法实现dp转px fun Int.dpToPx(context: Context): Int = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics ).toInt() class LevelGuideDecoration( private val indentWidth: Int = 20.dpToPx(context), // 每级缩进宽度 private val lineColor: Int = Color.GRAY, private val lineWidth: Int = 2.dpToPx(context) ) : RecyclerView.ItemDecoration() { private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = lineColor strokeWidth = lineWidth.toFloat() } override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, parent, state) val position = parent.getChildAdapterPosition(view) val item = yourDataList[position] // 替换为你自己的数据集 outRect.left = item.level * indentWidth } override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { super.onDraw(c, parent, state) for (i in 0 until parent.childCount) { val child = parent.getChildAt(i) val position = parent.getChildAdapterPosition(child) val item = yourDataList[position] // 绘制所有父层级的纵向引导线 for (level in 0 until item.level) { val lineX = level * indentWidth + indentWidth / 2f val lineBottom = if (item.isLastInGroup && level == item.level - 1) { child.top + child.height / 2f } else { child.bottom.toFloat() } c.drawLine(lineX, child.top.toFloat(), lineX, lineBottom, paint) } // 绘制当前条目的横向引导线 val horizontalStartX = item.level * indentWidth + indentWidth / 2f val horizontalY = child.top + child.height / 2f val horizontalEndX = item.level * indentWidth + indentWidth.toFloat() c.drawLine(horizontalStartX, horizontalY, horizontalEndX, horizontalY, paint) } } }
可用谷歌检索关键词
- Android RecyclerView ItemDecoration hierarchy guide line
- Kotlin RecyclerView tree view connector line
- Android nested list indent vertical horizontal line
- RecyclerView level item decoration draw line
内容的提问来源于stack exchange,提问作者joih
相关产品推荐
相关产品推荐

