BottomNavigationView切换Fragment时子Fragment残留问题求助
问题描述
现有Home、List、Settings三个主Fragment,其中List包含AddFormFragment和EditFormFragment两个子Fragment。使用底部导航切换三个主Fragment时一切正常,但进入List的某个子Fragment后直接切换到其他主Fragment,再切回List时会显示之前的子Fragment,必须点击返回才能回到List主Fragment。需求是切回List时直接显示List主Fragment,而非残留的子Fragment。
导航配置代码(nav_graph.xml)
<fragment android:id="@+id/homeFragment" android:name="com.somi.fidelitycardconnect.ui.home.HomeFragment" android:label="Home" tools:layout="@layout/fragment_home" /> <fragment android:id="@+id/settingsFragment" android:name="com.somi.fidelitycardconnect.ui.settings.SettingsFragment" android:label="Impostazioni" tools:layout="@layout/fragment_settings" /> <fragment android:id="@+id/listFragment" android:name="com.somi.fidelitycardconnect.ui.list.ListFragment" android:label="Lista clienti" tools:layout="@layout/fragment_list"> <action android:id="@+id/action_listFragment_to_addFormFragment" app:destination="@id/addFormFragment" /> <action android:id="@+id/action_listFragment_to_editFormFragment" app:destination="@id/editFormFragment" /> </fragment> <fragment android:id="@+id/addFormFragment" android:name="com.somi.fidelitycardconnect.ui.form.AddFormFragment" android:label="Aggiungi cliente" tools:layout="@layout/fragment_add_form"> </fragment> <fragment android:id="@+id/editFormFragment" android:name="com.somi.fidelitycardconnect.ui.form.EditFormFragment" android:label="Informazioni cliente" tools:layout="@layout/fragment_edit_form"> </fragment>
MainActivity代码
binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val navView: BottomNavigationView = binding.navView val navController = findNavController(R.id.nav_host_fragment_activity_main) // Passing each menu ID as a set of Ids because each // menu should be considered as top level destinations. appBarConfiguration = AppBarConfiguration( setOf( R.id.homeFragment, R.id.listFragment, R.id.settingsFragment ) ) setupActionBarWithNavController(navController, appBarConfiguration) navView.setupWithNavController(navController) } override fun onSupportNavigateUp(): Boolean { val navController = findNavController(R.id.nav_host_fragment_activity_main) return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() }
解决方案
自定义底部导航点击事件,强制回到List主Fragment
替换原有的navView.setupWithNavController(navController),改为自定义选中监听,当点击List项时,判断当前是否处于List的子Fragment,若是则直接回退到List主Fragment,否则正常导航:
binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val navView: BottomNavigationView = binding.navView val navController = findNavController(R.id.nav_host_fragment_activity_main) appBarConfiguration = AppBarConfiguration( setOf( R.id.homeFragment, R.id.listFragment, R.id.settingsFragment ) ) setupActionBarWithNavController(navController, appBarConfiguration) // 自定义底部导航选中逻辑 navView.setOnItemSelectedListener { menuItem -> when (menuItem.itemId) { R.id.homeFragment -> { navController.navigate(R.id.homeFragment) true } R.id.listFragment -> { // 若当前不在List主Fragment,直接回退到List主Fragment if (navController.currentDestination?.id != R.id.listFragment) { navController.popBackStack(R.id.listFragment, false) } true } R.id.settingsFragment -> { navController.navigate(R.id.settingsFragment) true } else -> false } } override fun onSupportNavigateUp(): Boolean { val navController = findNavController(R.id.nav_host_fragment_activity_main) return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() }
补充:优化导航栈的另一种写法
如果希望每次点击List项时都完全重置List的导航栈(避免栈中残留任何子Fragment),可以使用navigate方法配合popUpTo参数:
R.id.listFragment -> { navController.navigate(R.id.listFragment) { // 清空List主Fragment之上的所有栈元素 popUpTo(R.id.listFragment) { inclusive = false } // 避免重复点击时重复入栈 launchSingleTop = true } true }
内容的提问来源于stack exchange,提问作者Silvano M.
相关产品推荐
相关产品推荐

