changing progress bar as scrolling

144 Views Asked by At

I'm making a project in Kotlin that has a view with a long text inside a recyclerView. I wanted to put a linear progress bar to show how much text is left.

Currently I have this:

 binding.rvBody.setOnScrollChangeListener { _, _, _, _, oldScrollY ->
            // se computa el valor absoluto (queremos que total sea positivo)
            val total = binding.rvBody.height

            binding.progressBar?.apply {
                max = total
                progress += -oldScrollY
            }
            // si está arriba, el valor será 0
            if (!binding.rvBody.canScrollVertically(-1)) { // si no se puede hacer scroll hacia arriba
                binding.progressBar?.setProgressCompat(0, true)
            }
            // si está abajo, el valor será el total
            if (!binding.rvBody.canScrollVertically(1)) { // si no se puede hacer scroll hacia abajo
                binding.progressBar?.setProgressCompat(total, true)
            }
        }

The progressBar right now is moving as scrolling, but it gets to the end of the bar before getting to the end of the text, and it goes back to the begining of the bar also before getting to the begining again.

2

There are 2 best solutions below

2
zaid khan On

I had the same functionality working, I have a scroll view instead of a recycler view.

scroll is the id of ScrollView and progress is the ProgressBar

binding.scroll.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->

val totalScrollHeight = binding.scroll.getChildAt(0).height - binding.scroll.height

binding.progressBar.apply{

max=totalScrollHeight
progress=scrollY

}
}

This code is working perfectly hope it works at your end too :)

0
cactustictacs On

verticalScrollbarPosition doesn't do what you think it does.

public int getVerticalScrollbarPosition ()

Returns int The position where the vertical scroll bar will show, if applicable.

To make it clearer what it's actually returning, let's look at setVerticalScrollbarPosition:

public void setVerticalScrollbarPosition (int position)

Set the position of the vertical scroll bar. Should be one of SCROLLBAR_POSITION_DEFAULT, SCROLLBAR_POSITION_LEFT or SCROLLBAR_POSITION_RIGHT.

So verticalScrollbarPosition doesn't give you the position of the scrollable thumb as a percentage of the scrollbar's height, it just gives you a fixed constant that says where the scrollbar is drawn. So it's not what you're looking for, and never changes anyway.


I don't have time to experiment with this, but you probably want to use computeVerticalScrollOffset and computeVerticalScrollRange on the RecyclerView (which is inheriting those methods from its ScrollingView supertype) and calculate offset / range.toFloat(). It says the units are arbitrary, but consistent between the two, so that should give you the correct percentage (you need to convert to floating point so you don't just get 0 or 1 by dividing two ints)

Also you should be using addOnScrollListener really, seOnScrollChangeListener is deprecated!