在 RecyclerView 中减小滚动区域/滚动条大小。

3

我想减小recycler view的滚动条大小(见附图),我尝试过创建自定义drawable来设置Thumb和Track,但是thumb没有在track中正确显示。有人能帮我找到更好的方法吗?

enter image description here

在上面的图像中,底部有一个小尺寸的水平滚动条。我想实现类似于这样的效果。

enter image description here


你能更清楚地解释一下吗? - Arsh
@Arsh 在上面的图片中,您可以看到底部的水平滚动条非常小。我想要实现类似的效果。 - T_V
所以,当您滑动RecyclerView时,希望滚动条也随之移动。或者您只需在下方滚动条上滑动,RecyclerView将通过移动而滚动。 - Arsh
https://dev59.com/4KXja4cB1Zd3GeqPRHG_ 或许这可以帮到你。 - Arsh
@Arsh,所以您希望在滑动RecyclerView时,滚动条也随之移动。- 是的。 - T_V
你也可以使用ViewPager来实现这个功能。https://github.com/chahine/pageindicator - Aniruddh Parihar
2个回答

2
这是一种您可以实现所需目标的方法:
定义拇指:

enter image description here

custom_thumb.xml

<shape
    android:shape="rectangle">
    <corners android:radius="20dp" />
    <solid android:color="@android:color/holo_red_light" />
    <size
        android:width="40dp"
        android:height="10dp" />
</shape>

定义SeekBar的进度可绘制对象:

seekbar_drawable.xml

<layer-list>
    <item android:id="@android:id/progress">
        <clip android:drawable="@android:color/transparent" />
    </item>
</layer-list>

我们不会显示进度条的进度,所以我们将进度条的进度可绘制设置为“透明”。除了进度可绘制之外,我们将定义另一个视图,该视图将显示在进度条后面。为什么要这样做?因为SeekBar希望将拇指移动到进度区域之外,而我们希望拇指完全保持在进度区域内。第二个视图包含整个SeekBar以及一些左右两侧的区域来容纳拇指。

seekbar_background.xml

<shape>
    <corners android:radius="20dp"/>
    <solid android:color="@android:color/darker_gray" />
</shape>

这里有一些示例XML以展示它的样式:
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white">

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/seekbar_background"
        app:layout_constraintBottom_toBottomOf="@id/seekBar"
        app:layout_constraintEnd_toEndOf="@id/seekBar"
        app:layout_constraintStart_toStartOf="@id/seekBar"
        app:layout_constraintTop_toTopOf="@id/seekBar" />

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:max="10000"
        android:min="0"
        android:paddingStart="20dp"
        android:paddingEnd="20dp"
        android:progressDrawable="@drawable/seekbar_drawable"
        android:thumb="@drawable/custom_thumb"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

使用 SeekBar.OnSeekBarChangeListener来滚动RecyclerView,使用RecyclerView的滚动函数。当手动滚动RecyclerView时,使用 RecyclerView.OnScrollListener来设置seekbar的进度。您需要建立两个视图滚动状态之间的映射。
我已经在代码中硬编码了一些值,你可能需要进行调整。
可以使用以下代码以编程方式更改拇指的宽度,以调整为Recyclerview项目的数量或任何其他值。
例如,要将拇指的宽度增加一倍,可以执行以下操作:
val thumb = binding.seekBar.thumb as GradientDrawable
thumb.setSize(thumb.intrinsicWidth * 2, thumb.intrinsicHeight)

谢谢Cheticamp,这非常接近我所寻找的内容,但是这里的Thumb大小是固定的,但根据我的要求,随着RecyclerView中的项目增加,Thumb大小将会减小,我们能否通过编程方式设置Thumb大小或者其他方法来实现这一点。 - T_V
谢谢你提供的解决方案,但是你能否说明如何使用回收站的滚动条来移动寻找栏? - Moustafa EL-Saghier

1

您可以创建自己的自定义滚动条,并将其与回收视图绑定。 以下是用于处理上述制作的滚动条的回收视图扩展方法

fun RecyclerView.handleScroll(itemScrollerBinding: ItemScrollerBinding) {
    post {
        val parentWidth = itemScrollerBinding.parent.width
        val layoutParams = itemScrollerBinding.progress.layoutParams
        val initialX = itemScrollerBinding.progress.x
        layoutManager?.let {
            val totalWidth = this.computeHorizontalScrollRange()
            val visibleWidth = this.computeHorizontalScrollExtent()
            val percent =
                visibleWidth.toFloat() / totalWidth.toFloat()
            layoutParams.width = (parentWidth * percent).toInt()
            itemScrollerBinding.progress.layoutParams = layoutParams
            addOnScrollListener(object :
                RecyclerView.OnScrollListener() {
                override fun onScrolled(
                    recyclerView: RecyclerView,
                    dx: Int,
                    dy: Int,
                ) {
                    super.onScrolled(recyclerView, dx, dy)
                    val scrolledWidth =
                        this@handleScroll.computeHorizontalScrollOffset()
                    val updatedVisibleWidthRecyclerView =
                        visibleWidth + scrolledWidth
                    val scrolledWidthScroller =
                        ((parentWidth.toFloat() / totalWidth) * scrolledWidth)
                    itemScrollerBinding.progress.x =
                        initialX + scrolledWidthScroller
                }
            })
        }
    }
}

以下是ItemScrollerBinding的XML代码。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    android:layout_width="@dimen/size_48"
    android:layout_height="@dimen/size_6"
    android:background="@drawable/bg_scroller_background">
    <LinearLayout
        android:id="@+id/progress"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="@drawable/bg_scroller"
        android:orientation="horizontal" />
</FrameLayout>

您可以将此放置在回收视图下方并居中显示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接