Even though this question is a little old and ScrollView
are not as used, I had to implement something related to this, I'm using a NestedScrollView
per recommendation and Kotlin.
If you are using Java this won't be possible or as 'clean', you would need to create static util methods instead, with Kotlin you can do extension functions as shown.
If you are using a ScrollView
just change what you see here from NestedScrollView
to ScrollView
.
I'll show two ways to implement this:
First, create your NestedScrollViewExtensions.kt
file:
1.
If you want a simplified (my preferred) version just add this snippet to your NestedScrollViewExtensions.kt
file:
fun NestedScrollView.onScrollStateChanged(startDelay: Long = 100, stopDelay: Long = 400, listener: (Boolean) -> Unit) {
setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_MOVE -> {
handler.postDelayed({
listener.invoke(true)
}, startDelay)
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
handler.postDelayed({
listener.invoke(false)
}, stopDelay)
}
}
false // Do not consume events
}
}
This way the implementation is cleaner:
scroll_view.onScrollStateChanged { isScrolling ->
if(isScrolling) fab.shrink() else fab.extend()
}
2
And the not so clean way
interface NestedViewScrollChangedListener {
fun onScrollStart()
fun onScrollStop()
}
@SuppressLint("ClickableViewAccessibility")
fun NestedScrollView.onScrollStateChanged(listener: NestedViewScrollChangedListener) {
this.setOnTouchListener { _, event ->
when(event.action) {
MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_MOVE -> {
handler.postDelayed({
listener.onScrollStart()
}, 100)
}
MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
handler.postDelayed({
listener.onScrollStop()
}, 400)
}
}
false // Don't consume touch events
}
}
In here I'm using a simple delay that works for me as I need to have an animation happen, feel free to remove all the handler.postDelay()
and call the listener directly.
The interface above NestedViewScrollChangedListener
needs to be implemented like this:
scroll_view.onScrollStateChanged(object : NestedViewScrollChangedListener {
override fun onScrollStart() {
fab.shrink()
}
override fun onScrollStop() {
fab.extend()
}
})
Good luck :)