Last active
February 21, 2019 19:25
-
-
Save ZacSweers/6827d816292731a5e98d2be28283f535 to your computer and use it in GitHub Desktop.
Observable stream of AppBarLayout offsets + scroll direction from https://twitter.com/pandanomic/status/898142281106022400
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Here we want to get the appbar offset changes paired with the direction it's moving and | |
* using RxBinding's great `offsetChanges` API to make an rx Observable of this. The first | |
* part buffers two while skipping one at a time and emits y delta pairs (cur and prev). Second | |
* part is just a simple map to pair the offset with the resolved scroll direction comparing | |
* to the previous offset. This gives us a nice stream of (offset, direction) emissions. | |
* | |
* Note that the filter() is important if you manipulate child views of the ABL. If any child | |
* view requests layout again, it will trigger an emission from the offset listener with the | |
* same value as before, potentially causing measure/layout/draw thrashing if your logic | |
* reacting to the offset changes *is* manipulating those child views (vicious cycle). | |
*/ | |
RxAppBarLayout.offsetChanges(appBarLayout) | |
.buffer(2, 1) // Buffer in pairs to compare the previous, skip 1 at a time | |
.filter { it[1] != it[0] } | |
.map { Pair(it[1], ScrollDirection.resolve(it[1], it[0])) } // Map to a direction | |
.subscribe { (offset, direction) -> | |
// Profit | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum class ScrollDirection { | |
UP, DOWN; | |
companion object { | |
fun resolve(current: Int, prev: Int): ScrollDirection { | |
return if (current > prev) { | |
DOWN | |
} else { | |
UP | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment