I want to reduce scrollbar size(attached image) for recycler view, I have tried with creating custom drawable for for Thumb & Track, but thumb is not underlying with in the track. Can someone help me in better approach to achieve this?

In above image, horizontal scrollbar at bottom which is small in size. I want to achieve something like this.

Here is one way that you can do what you want:
Define the thumb:

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>
Define the progress drawable for the seekbar:
seekbar_drawable.xml
<layer-list>
<item android:id="@android:id/progress">
<clip android:drawable="@android:color/transparent" />
</item>
</layer-list>
We will not show the progress for the seekbar, so we set the progress drawable to "transparent". Instead of the progress drawable, we will define another view that will show behind the progress bar. Why do we do this? It is because the seekbar wants to move the thumb outside the progress area and we want the thumb to remain entirely within the progress area. The second view encompasses all of the seekbar plus some area to the left and to the right to contain the thumb.
seekbar_background.xml
<shape>
<corners android:radius="20dp"/>
<solid android:color="@android:color/darker_gray" />
</shape>
Here is some sample XML to show how this looks:
<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>

Use a SeekBar.OnSeekBarChangeListener to scroll the RecyclerView using the RecyclerView's scrolling functions. When the RecyclerView is scrolled manually, use a RecyclerView.OnScrollListener to set the seekbar's progress. You will have to establish the mapping of the two views scroll states.
I have hard-coded some values that you will probably need to adjust.
One can change the width of the thumb programmatically with the following code to adjust for number of Recyclerview items or to any other value.
To change the width of the thumb by a factor of two as an example, you can do the following:
val thumb = binding.seekBar.thumb as GradientDrawable
thumb.setSize(thumb.intrinsicWidth * 2, thumb.intrinsicHeight)
You can create your own custom scrollbar and tie it with recycler view. Following is extension method for recycler view to handle the above made scrollbar
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 =
[email protected]()
val updatedVisibleWidthRecyclerView =
visibleWidth + scrolledWidth
val scrolledWidthScroller =
((parentWidth.toFloat() / totalWidth) * scrolledWidth)
itemScrollerBinding.progress.x =
initialX + scrolledWidthScroller
}
})
}
}
}
Following is xml code for ItemScrollerBinding
<?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>
You can place this below the recycler view and center it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With