Stop fragment refresh in bottom nav using navhost

后端 未结 8 1664
夕颜
夕颜 2020-12-31 12:14

This problem has been asked a few times now, but we are in 2020 now, did anyone find a good usable solution to this yet?

I want to be able to navigate using the bott

相关标签:
8条回答
  • 2020-12-31 12:58

    The simple solution to stop refreshing on multiple clicks on the same navigation item could be

     binding.navView.setOnNavigationItemSelectedListener { item ->
            if(item.itemId != binding.navView.selectedItemId)
                NavigationUI.onNavDestinationSelected(item, navController)
            true
        }
    

    where binding.navView is the reference for BottomNavigationView using Android Data Binding.

    0 讨论(0)
  • 2020-12-31 12:58

    create a class:

    @Navigator.Name("keep_state_fragment") // `keep_state_fragment` is used in navigation xml 
    class KeepStateNavigator(
    private val context: Context,
    private val manager: FragmentManager, // Should pass childFragmentManager.
    private val containerId: Int
    ) : FragmentNavigator(context, manager, containerId) {
    
    override fun navigate(
        destination: Destination,
        args: Bundle?,
        navOptions: NavOptions?,
        navigatorExtras: Navigator.Extras?
    ): NavDestination? {
        val tag = destination.id.toString()
        val transaction = manager.beginTransaction()
    
        var initialNavigate = false
        val currentFragment = manager.primaryNavigationFragment
        if (currentFragment != null) {
            transaction.detach(currentFragment)
        } else {
            initialNavigate = true
        }
    
        var fragment = manager.findFragmentByTag(tag)
        if (fragment == null) {
            val className = destination.className
            fragment = manager.fragmentFactory.instantiate(context.classLoader, className)
            transaction.add(containerId, fragment, tag)
        } else {
            transaction.attach(fragment)
        }
    
        transaction.setPrimaryNavigationFragment(fragment)
        transaction.setReorderingAllowed(true)
        transaction.commitNow()
    
        return if (initialNavigate) {
            destination
        } else {
            null
        }
    }
    }
    

    Use keep_state_fragment instead of fragment in nav_graph

    In Activity:

    val navController = findNavController(R.id.nav_host_fragment)
    
        // get fragment
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)!!
        // setup custom navigator
        val navigator = KeepStateNavigator(this, navHostFragment.childFragmentManager, R.id.nav_host_fragment)
        navController.navigatorProvider += navigator
    
        // set navigation graph
        navController.setGraph(R.navigation.nav_graph)
        bottom_navigation.setupWithNavController(navController)
    
    0 讨论(0)
提交回复
热议问题