Last active
February 10, 2021 14:09
-
-
Save cmorigaki/20104da5de3c2b36c7d401e574025e2b to your computer and use it in GitHub Desktop.
[Nested RecyclerView State] - Scrolling vertically
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
| 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