RecyclerView自定义滚动条

2,879 阅读1分钟

直接上图

为了实现这样的效果,网上查了资料发现没有比较简洁的实现方式,然后就自己来了,

由于是在现有代码的基础上,进行样式改造,所有首要需要考虑低侵入性,这时候就想到了RecyclerView.ItemDecoration,

既然有了思路,那就直接开动干,贴代码

class HorizontalScrollBarDecoration: RecyclerView.ItemDecoration() {
    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State?) {
        super.onDrawOver(c, parent, state)

        val barHeight = SizeUtils.dp2px(2f)
        val scrollWidth = SizeUtils.dp2px(20f)
        val indicatorWidth = SizeUtils.dp2px(6f)
        val paddingBottom = SizeUtils.dp2px(9f)
        val barX = (parent.width / 2 - scrollWidth / 2).toFloat()
        val barY = (parent.height - paddingBottom - barHeight).toFloat()

        val paint = Paint()
        paint.isAntiAlias = true
        paint.color = Color.parseColor("#FFEAF1FE")
        paint.strokeCap = Paint.Cap.ROUND
        paint.strokeWidth = barHeight.toFloat()
        c.drawLine(barX, barY, barX + scrollWidth.toFloat(), barY, paint)

        val extent = parent.computeHorizontalScrollExtent()
        val range = parent.computeHorizontalScrollRange()
        val offset = parent.computeHorizontalScrollOffset()
        val maxEndX = (range - extent).toFloat()
        //可滑动
        if (maxEndX > 0) {
            val proportion = offset / maxEndX

            val scrollableDistance = scrollWidth - indicatorWidth

            val offsetX = scrollableDistance * proportion
            paint.color = Color.parseColor("#FF327BF9")
            c.drawLine(barX + offsetX, barY, barX + indicatorWidth.toFloat() + offsetX, barY, paint)
        } else {
            paint.color = Color.parseColor("#FF327BF9")
            c.drawLine(barX, barY, barX + scrollWidth.toFloat(), barY, paint)
        }
    }
}

Usage

recyclerView.addItemDecoration(HorizontalScrollBarDecoration())

直接上效果

如此,就在尽少改动原有逻辑的基础上,实现了样式变动