使用导航组件为每个片段自定义工具栏



我将导航组件与单个活动一起使用。为每个片段创建自定义工具栏的想法。例如,一个工具栏必须是黄色的,另一个是带有菜单图标的紫色,还有一个是透明的。如果可能的话,我想通过MainActivity中的setupActionBarWithNavController(navController)保存导航和工具栏之间的连接来实现它。我试着在Fragment中使用这种方法(activity as? AppCompatActivity)?.setSupportActionBar(toolbar),但它复制了工具栏。

这是我的主题

<style name="Theme.Movies" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>

这是MainActivity布局中的工具栏

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/purple_700"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_constraintTop_toTopOf="parent" />

这是MainActivity

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

setSupportActionBar(toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
setupActionBarWithNavController(navController)
bottom_nav.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp() || super.onSupportNavigateUp()
}
}

我尝试使用此方法(活动为?AppCompatActivity(?。片段中的setSupportActionBar(工具栏(,但它复制了工具栏。

这是意料之中的事,因为工具栏由活动托管,并且Jetpack导航架构组件使用单个活动模型,所以该活动托管的所有navGraph片段都共享该工具栏(因为它是活动的一部分(。

因此,再次重置工具栏将复制它。

解决方案是从活动中删除工具栏,并在每个片段布局中使用唯一的工具栏,这样当一个片段与另一个片段进行事务处理时;旧片段的布局被新片段的新布局所取代,所以旧的工具栏不见了,我们有了一个新的工具栏;此时您需要为新工具栏调用setSupportActionBar(toolbar)

但请注意,每次调用setSupportActionBar(toolbar)时都必须调用setupActionBarWithNavController(),因为它需要附加到新工具栏上。

更新

所以,我必须调用片段中的setSupportActionBar(工具栏(和setupActionBarWithNavController((?

实际上,您可以在活动中调用setSupportActionBar(toolbar)。但你可以在片段中使用requireActivity()来做到这一点:

为了不重复事情,你可以有一个功能活动来做:

活动中:

fun setupActionBar(toolBar: Toolbar) {
setSupportActionBar(toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
setupActionBarWithNavController(navController)

}   

并且在片段中:

val toolbar = findViewById<Toolbar>(R.id.foo)
(requireActivity() as MainActivity).setupActionBar(toolbar)

最新更新