Android Jetpack Navigation 如何处理 Toolbar 和 BottomNavBar 内容
Android Jetpack Navigation How to handle the Toolbar and BottomNavBar content
我对导航组件如何适应应用程序行为感到有点困惑。在教程中,一切看起来都不错而且闪亮,你不会做太复杂的事情,但在实际应用程序中实施时,情况似乎有所不同。
导航前
在实施导航之前,我不得不手动 运行 分段交易。为了做到这一点,我的片段将实现一个接口 onFragmentAction
,它将 bundle
传递给主 Activity
并在 activity 中基于操作,替换当前片段与另一个。
第二个需要处理的部分是顶部工具栏和 BottomAppBar
。例如 BottomAppBar
需要让 FAB
在某些片段上以不同方式对齐或隐藏在其他片段中。此外,顶部 ToolBar
需要在某些上展开或在其他上折叠。为此,我听取了 FragmentManager.OnBackStackChangedListener
并根据片段标记 getSupportFragmentManager().getBackStackEntryAt(size - 1).getName()
相应地更改了布局。
带导航
第一部分似乎很容易做:传递参数并开始新的片段。但我不知道导航是否可以处理工具栏管理,或者我需要从我的 Activity 继续管理它。
工具栏标题是根据导航图中的 'label' 值设置的,如果您想对工具栏或 BottomAppBar 做一些不同的事情,您可以在 activity 中添加 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 的解决方案有效,但我不推荐将其用于管理工具栏。
工具栏应该是片段布局的一部分,每个片段都应该管理自己的工具栏。您可以为每个片段添加不同的菜单。即使在想要在 activity 中使用工具栏的情况下,我也建议获取对工具栏形式 activity 的引用(通过界面),然后在片段本身中添加和操作其项目。
这将分离您的 activity 和片段(这是拥有导航图和路由器的目标之一)。一个好的经验法则是假设您想删除片段,那么您不需要对 activity.
进行任何更改
在你的片段中:
NavController navHostFragment = NavHostFragment.findNavController(this);
NavigationUI.setupWithNavController(toolbar, navHostFragment);
当我单击列表项 (Explore Fragment
) 上的项目时,它会否定 DetailFragment
,当我单击工具栏上的后退按钮时,它会 return MainFragment
.
如果您想通过调用菜单项到达另一个片段,您必须为项目 id 提供与目标 id 中相同的 id。
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"
/>
我对导航组件如何适应应用程序行为感到有点困惑。在教程中,一切看起来都不错而且闪亮,你不会做太复杂的事情,但在实际应用程序中实施时,情况似乎有所不同。
导航前
在实施导航之前,我不得不手动 运行 分段交易。为了做到这一点,我的片段将实现一个接口 onFragmentAction
,它将 bundle
传递给主 Activity
并在 activity 中基于操作,替换当前片段与另一个。
第二个需要处理的部分是顶部工具栏和 BottomAppBar
。例如 BottomAppBar
需要让 FAB
在某些片段上以不同方式对齐或隐藏在其他片段中。此外,顶部 ToolBar
需要在某些上展开或在其他上折叠。为此,我听取了 FragmentManager.OnBackStackChangedListener
并根据片段标记 getSupportFragmentManager().getBackStackEntryAt(size - 1).getName()
相应地更改了布局。
带导航
第一部分似乎很容易做:传递参数并开始新的片段。但我不知道导航是否可以处理工具栏管理,或者我需要从我的 Activity 继续管理它。
工具栏标题是根据导航图中的 'label' 值设置的,如果您想对工具栏或 BottomAppBar 做一些不同的事情,您可以在 activity 中添加 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 的解决方案有效,但我不推荐将其用于管理工具栏。
工具栏应该是片段布局的一部分,每个片段都应该管理自己的工具栏。您可以为每个片段添加不同的菜单。即使在想要在 activity 中使用工具栏的情况下,我也建议获取对工具栏形式 activity 的引用(通过界面),然后在片段本身中添加和操作其项目。
这将分离您的 activity 和片段(这是拥有导航图和路由器的目标之一)。一个好的经验法则是假设您想删除片段,那么您不需要对 activity.
进行任何更改在你的片段中:
NavController navHostFragment = NavHostFragment.findNavController(this);
NavigationUI.setupWithNavController(toolbar, navHostFragment);
当我单击列表项 (Explore Fragment
) 上的项目时,它会否定 DetailFragment
,当我单击工具栏上的后退按钮时,它会 return MainFragment
.
如果您想通过调用菜单项到达另一个片段,您必须为项目 id 提供与目标 id 中相同的 id。
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"
/>