epoxy icon indicating copy to clipboard operation
epoxy copied to clipboard

What is the proper way to save the scroll position in an EpoxyRecyclerView?

Open martymiller opened this issue 2 years ago • 9 comments

When I use the back button to return to my Fragment (which is only a vertical EpoxyRecyclerView using MvRx) it starts at the top of the list instead of the screen. This is probably annoying for users who click on a photo, see the full screen image, and then end up at the top of the screen when hitting back. Is this something Android should be doing automatically? Should I be storing the scroll position in onSavedInstanceState? Or does Epoxy have some other solution?

I know that I can set saveViewState on Models, but I don't see how this would help the RecyclerView resume at the previous scroll position.

martymiller avatar Mar 23 '22 19:03 martymiller

I have the same problem ! I use carousel within a vertical RecyclerView+Navigation,but carousel not saved the position.

guozhiqiang123 avatar Mar 27 '22 03:03 guozhiqiang123

Perhaps it is worth checking where the controller is being initialized, I have faced this issue when controllers are initialized/loaded during the onStart or onResume methods of Fragment however when it is done during the onCreateView method, it worked as expected.

abdul-hasib avatar Apr 20 '22 05:04 abdul-hasib

I have the same problem ! I use carousel within a vertical RecyclerView+Navigation,but carousel not saved the position.

The location information can be saved. The Navigation I am currently using is the latest version, and it is done in combination with mavericks and epoxy. The scrolling position can also be saved when rotating the screen.But I haven't tried the compose version yet. (可以保存位置信息,我目前使用的Navigation是最新版,以及mavericks结合epoxy来做的,旋转屏幕时滚动的位置一样可以保存,不过compose版本的我还没试过)

xuexixuexijpg avatar Jun 01 '22 14:06 xuexixuexijpg

I am also having this exact same issue where nested recyclerview contains horizontal carousel and whenever I navigate to other page and back, the carousels position is not retained - I have overridden shouldSaveViewState and I have tried to initialize controller in onViewCreated and in onCreate without good results

Veeksi avatar Jun 05 '22 11:06 Veeksi

I am also having this exact same issue where nested recyclerview contains horizontal carousel and whenever I navigate to other page and back, the carousels position is not retained - I have overridden shouldSaveViewState and I have tried to initialize controller in onViewCreated and in onCreate without good results

This is indeed the case. I did the same thing. Although my original method kept the scroll position, the adapter leaked. Now if I use this, it is no problem to empty the adapter when I leave the window, but the original scroll state is gone. I don't know how to solve it, maybe I can rewrite the navigation component to not destroy the view when navigating?Just overlay the view. This is the BaseEpoxyFragment I wrote while practicing.

xuexixuexijpg avatar Jun 08 '22 13:06 xuexixuexijpg

I added onScrollListener to my EpoxyRecyclerView, than i use findLastCompletelyVisibleItemPosition() on every scroll, in this way i got the position and saved it. And after that i can scroll to this position anytime

Kudlayra avatar Feb 02 '23 19:02 Kudlayra

Share us your implemented code.

viroth-ty avatar Feb 03 '23 01:02 viroth-ty

this code will save current visible position on every scroll:

var position = 0
binding.epoxyRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
     override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                position = (recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
     }
}

then we can scroll to this position this way: binding.epoxyRecyclerView.scrollToPosition(position)

in my case it helped

Kudlayra avatar Feb 03 '23 09:02 Kudlayra

This should work!

private val uiController: UIController by lazy {
    UIController()
}


override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    uiController.onSaveInstanceState(outState)
}


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    uiController.onRestoreInstanceState(savedInstanceState)
}

viroth-ty avatar Feb 12 '23 09:02 viroth-ty