airbnb / epoxy

Epoxy is an Android library for building complex screens in a RecyclerView
https://goo.gl/eIK82p
Apache License 2.0
8.46k stars 730 forks source link

Carousel resets position to head when using Navigation Component #1369

Closed shawnlinboy closed 7 months ago

shawnlinboy commented 7 months ago

Preconditions

Test

I wrote a demo to elaborate this issue, see: https://github.com/shawnlinboy/epoxy-carousel-issue/tree/master

viroth-ty commented 7 months ago

Navigation component using fragment as views, so in order to save state you need to :

private val controller: YourController by lazy {
    YourController()
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    controller.onSaveInstanceState(outState)
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    controller.onRestoreInstanceState(savedInstanceState)
}

Store data in ViewModel with Live data or using mavericks

shawnlinboy commented 7 months ago

Navigation component using fragment as views, so in order to save state you need to :

private val controller: YourController by lazy {
    YourController()
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    controller.onSaveInstanceState(outState)
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    controller.onRestoreInstanceState(savedInstanceState)
}

Store data in ViewModel with Live data or using mavericks

Well, I think I've solve this issue now, thanks for the inspiration!

The detail was that navigating throngh fragments with Navigation component did not trigger source fragment's onSaveInstanceState(Bundle) except the fragment's host activity calls its own onSaveInstanceState(Bundle)(Ref), this condition is so harsh like it tends to only happen when the screen is rotated or so. However, I got inspired by migrating the "save and restore combo" from fragment's onSaveInstanceState and onCreate to onDestroyView and onViewCreated, and it works. :)

I've uploaded this workaround to this CL, and hope it helps others.