我对导航组件如何适应应用程序行为感到困惑。在教程中看起来很漂亮和闪亮,你不会做太复杂的事情,但在实际的应用程序中实现时,事情似乎有所不同。
导航之前
在实现导航之前,我不得不手动运行片段事务。为了做到这一点,我的片段将实现一个接口onFragmentAction
,它将bundle
传递给主Activity
,并在基于动作的活动中,用另一个替换当前片段。
需要处理的第二部分是顶部工具栏和BottomAppBar
。例如,BottomAppBar
需要让FAB
在某些片段上对齐不同或在其他片段中隐藏。顶部的ToolBar
也需要在某些地方扩展或在其他地方崩溃。为此,我听了FragmentManager.OnBackStackChangedListener
并基于片段标签getSupportFragmentManager().getBackStackEntryAt(size - 1).getName()
相应地更改了布局。
随着导航
第一部分似乎很容易做到:传递参数并开始新的碎片。但我不知道导航是否可以处理工具栏管理,或者我需要继续从我的Activity管理它。
工具栏标题是根据导航图中的“标签”值设置的,如果您想要使用工具栏或BottomAppBar执行不同的操作,可以在活动中添加addOnNavigatedListener,并根据当前目标执行某些操作。
findNavController(nav_host_fragment).addOnNavigatedListener { controller,
destination ->
when(destination.id) {
R.id.destination1 -> {
//Do something with your toolbar or BottomAppBar
}
R.id.destination2 -> {
//Do something with your toolbar or BottomAppBar
}
}
}
即使Alex的解决方案有效,我也不建议将其用于管理工具栏。
工具栏应该是片段布局的一部分,每个片段应该管理自己的工具栏。你可以为每个片段充气不同的菜单。即使在想要在活动中使用工具栏的情况下,我建议获得对工具栏表单活动的引用(通过接口),然后在片段本身中添加和操作其项目。
这将解耦您的活动和片段(这是导航图和路由器的目标之一)。一个好的经验法则是想象你想要删除片段,那么你不应该对活动做任何改变。
在你的片段中:
NavController navHostFragment = NavHostFragment.findNavController(this);
NavigationUI.setupWithNavController(toolbar, navHostFragment);
当我单击列表项(Explore Fragment
)上的项目时,它将否定DetailFragment
,当我单击工具栏上的后退按钮时,它将返回MainFragment
。
如果要通过调用菜单项来访问另一个片段,则必须为项目标识赋予目标标识中相同的标识。
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return
item.onNavDestinationSelected(findNavController(R.id.nav_host_fragment))
|| super.onOptionsItemSelected(item)
}
<item android:id="@+id/dailyInfoFragment"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="never"/>
<fragment
android:id="@+id/dailyInfoFragment"
android:name="com.example.sonyadmin.infoPerDay.DailyInfoFragment"
android:label="fragment_daily_info"
tools:layout="@layout/fragment_daily_info"
/>