简体   繁体   中英

How to save fragment state in bottom navigation

I know this question has been asked by others but I could not find anyone to help myself. I have a bottom navigation view with three fragments.

When I navigate out of the activity where this bottom nav is I want to be able to save the last visited fragment in the bottom nav and when return restores it.

Currently, that is been done using bottomNav.selectedItemId , however, the fragment changes are not accompanied. It restores a blank screen except that I navigate to another fragment in the bottom nav and back. How can I restore the fragment with its current data?


    val title: String by lazy {
        getName()
    }
    val profileName by lazy {
        profile_drawer_view.findViewById<TextView>(R.id.profile_name)
    }

    //    Get logged-in user
    private val currentUser: User? by lazy {
        authViewModel.currentUser
    }

    private val header by lazy {
        authViewModel.header
    }


    @Inject
    lateinit var viewModelProviderFactory: ViewModelFactory
    private val authViewModel: AuthViewModel by lazy {
        ViewModelProvider(this, viewModelProviderFactory).get(AuthViewModel::class.java)
    }


    val checkConnectionTv by lazy{
        dialog.findViewById<TextView>(R.id.loader_layout_tv)
    }

    lateinit var navController:NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dashboard)
        changeStatusBarColor(R.color.colorWhite)
        i(title, "Oncreate")

        navController = Navigation.findNavController(this, R.id.dashboard_fragment)

        bottomNav.setupWithNavController(navController)

//

    

    }


    private fun logoutRequest() {
        authViewModel.logout(this)
    }


    override fun onStart() {
        super.onStart()
        bottomNav.selectedItemId = authViewModel.lastFragmentId
        Log.i(title, "onStart")
    }


    override fun onPause() {
        super.onPause()
        authViewModel.lastFragmentId = bottomNav.selectedItemId
    }

    override fun onRestart() {
        super.onRestart()
        i(title, "Restart")
    }

    override fun onDestroy() {
        super.onDestroy()
        i(title, "onDestroy")

    }

}

I have faced the similar issue. You should move all the fragment's network or database related function to the activity's viewmodel and use a sharedViewModel in all the fragments. This will ensure that fragment's data is not reloaded when you visit it again.

Actually, the navigation component only supports replace fragment, not the add fragment. This causes your data to get lost and require fetching it again.

As of right now this is a known issue with the Navigation Component and they are still working on it for future releases.

you can use what tronku suggested by creating a shared viewmodel and whenever you navigate to a screen inside a fragment, save that state in there, and whenever you re-load the fragment from the start, check that shared viewmodel for any previously saved states and load them if found or load the start if it's empty.

I think you will have to save the entire stack trace inside that parent fragment though, since you will need to manually handle the back presses then.

I think I forgot to mention that I was using navigation component with the bottom navigation.

I was able to save and restored last fragment visited using the navcontroller

navController.navigate(authViewModel.lastFragmentId ?: R.id.profileFragment)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM