Bottom Navigation 如何从Fragment内部实现Fragment切换
实现方案
这里提供两种无耦合的实现方式,触发逻辑完全在Fragment1内部完成,不需要主动调用Activity的自定义方法:
方案1:共享ViewModel(通用方案,不限导航组件)
核心思路是通过和宿主Activity共享作用域的ViewModel传递导航事件,Activity仅做一次性的事件监听逻辑,后续所有Fragment切换都不需要修改Activity代码。
- 步骤1:创建全局导航共享ViewModel
class NavViewModel : ViewModel() { private val _targetTabId = MutableLiveData<Int>() val targetTabId: LiveData<Int> = _targetTabId fun switchTab(tabMenuId: Int) { _targetTabId.postValue(tabMenuId) } }
- 步骤2:在宿主Activity中添加一次性监听逻辑
class MainActivity : AppCompatActivity() { private lateinit var bottomNav: BottomNavigationView private lateinit var navViewModel: NavViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) bottomNav = findViewById(R.id.bottom_nav_view) // 初始化Activity作用域的ViewModel navViewModel = ViewModelProvider(this)[NavViewModel::class.java] // 监听导航事件,自动切换Tab navViewModel.targetTabId.observe(this) { menuId -> bottomNav.selectedItemId = menuId } } }
- 步骤3:在Fragment1内部直接触发切换
class Fragment1 : Fragment() { // 获取和宿主Activity共享的ViewModel private val navViewModel by activityViewModels<NavViewModel>() // 需要切换的场景下调用该方法即可,比如按钮点击回调中 private fun jumpToFragment2() { // 传入BottomNavigation菜单中Fragment2对应的item id navViewModel.switchTab(R.id.menu_fragment2) } }
方案2:Jetpack Navigation组件专属方案
如果你已经用Jetpack Navigation绑定了BottomNavigationView,直接在Fragment内获取NavController跳转即可,会自动同步BottomNavigation的选中状态:
class Fragment1 : Fragment() { private fun jumpToFragment2() { // R.id.fragment2 为NavGraph中Fragment2对应的目的地id,需要和BottomNavigation菜单id一致 findNavController().navigate(R.id.fragment2) } }
注意:不要采用强转Activity类型调用自定义方法的实现,会导致Fragment和宿主高度耦合,后续维护成本极高。
内容的提问来源于stack exchange,提问作者Bhavesh Purohit
相关产品推荐
相关产品推荐

