Skip to content

Instantly share code, notes, and snippets.

@cmorigaki
Last active February 10, 2021 14:09
Show Gist options
  • Select an option

  • Save cmorigaki/20104da5de3c2b36c7d401e574025e2b to your computer and use it in GitHub Desktop.

Select an option

Save cmorigaki/20104da5de3c2b36c7d401e574025e2b to your computer and use it in GitHub Desktop.
[Nested RecyclerView State] - Scrolling vertically
abstract class NestedRecyclerViewStateRecoverAdapter<T, VH : RecyclerView.ViewHolder>(
diffUtil: DiffUtil.ItemCallback<T>
) : ListAdapter<T, VH>(diffUtil) {
private val layoutManagerStates = hashMapOf<String, Parcelable?>()
@CallSuper
override fun onViewRecycled(holder: VH) {
if (holder is NestedRecyclerViewViewHolder) {
// Save the scroll position state (LayoutManager state)
val state = holder.getLayoutManager()?.onSaveInstanceState()
layoutManagerStates[holder.getId()] = state
}
super.onViewRecycled(holder)
}
@CallSuper
override fun onBindViewHolder(holder: VH, position: Int) {
if (holder is NestedRecyclerViewViewHolder) {
holder.getLayoutManager()?.let {
// Retrieve and set the saved LayoutManager state
val state: Parcelable? = layoutManagerStates[holder.getId()]
if (state != null) {
it.onRestoreInstanceState(state)
} else {
// We need to reset the scroll position when no state needs to be restored
it.scrollToPosition(0)
}
}
}
}
}
// ViewHolders containing a RecyclerView should inherit this interface.
// An alternative solution could be manually searching if the view constains a RecyclerView
interface NestedRecyclerViewViewHolder {
fun getId(): String
fun getLayoutManager(): RecyclerView.LayoutManager?
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment