Skip to content

Instantly share code, notes, and snippets.

@leonardoaramaki
Last active April 19, 2021 09:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leonardoaramaki/bc4337e3faa0f103728caf414c1a1ecc to your computer and use it in GitHub Desktop.
Save leonardoaramaki/bc4337e3faa0f103728caf414c1a1ecc to your computer and use it in GitHub Desktop.
Keep RecyclerView vertical scroll offset after layout resizing due to the keyboard being shown.
private var verticalScrollOffset = AtomicInteger(0)
recyclerView.addOnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom ->
val y = oldBottom - bottom
if (y.absoluteValue > 0) {
recyclerView.post {
if (y > 0 || verticalScrollOffset.get().absoluteValue >= y.absoluteValue) {
recyclerView.scrollBy(0, y)
} else {
recyclerView.scrollBy(0, verticalScrollOffset.get())
}
}
}
}
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
var state = AtomicInteger(RecyclerView.SCROLL_STATE_IDLE)
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
state.compareAndSet(RecyclerView.SCROLL_STATE_IDLE, newState)
when (newState) {
RecyclerView.SCROLL_STATE_IDLE -> {
if (!state.compareAndSet(RecyclerView.SCROLL_STATE_SETTLING, newState)) {
state.compareAndSet(RecyclerView.SCROLL_STATE_DRAGGING, newState)
}
}
RecyclerView.SCROLL_STATE_DRAGGING -> {
state.compareAndSet(RecyclerView.SCROLL_STATE_IDLE, newState)
}
RecyclerView.SCROLL_STATE_SETTLING -> {
state.compareAndSet(RecyclerView.SCROLL_STATE_DRAGGING, newState)
}
}
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (state.get() != RecyclerView.SCROLL_STATE_IDLE) {
verticalScrollOffset.getAndAdd(dy)
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment