免责声明
基于@Rajarshi 原始实验,我为这个问题制定了一个可行的解决方案。我不确定是最优雅的,还是有更好的方法。但经过数小时的研究和调查,这是我找到的最佳解决方案。
解决方案
分别膨胀工具栏并存储它们的引用,这样它们就不会被垃圾收集器拾取。OnDestinationChangedListener
然后在为您的 navController 自定义定义的主 AppBarLayout 中按需加载每个
例子
这是我用 Kotlin 编写的示例。
在您的 activity.xml 布局上,定义一个空的 AppBarLayout。
布局/activity.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
...
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay" />
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
在单独的布局文件中定义您的应用程序需要具有的工具栏。
布局/工具栏_defaul.xml
<com.google.android.material.appbar.MaterialToolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/default_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:menu="@menu/menu_default"
app:popupTheme="@style/AppTheme.PopupOverlay" />
布局/工具栏2.xml
<com.google.android.material.appbar.MaterialToolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar2"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:menu="@menu/menu2"
app:popupTheme="@style/AppTheme.PopupOverlay" />
在您的主要(也是唯一的)活动中,将 AppBar 相关组件声明为类属性,以便垃圾收集器不会拾取它们。
活动.kt
class Activity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var appBarLayout: AppBarLayout
private lateinit var defaultToolbar: MaterialToolbar
private lateinit var toolbar2: MaterialToolbar
...
最后,在onCreate
方法中,OnDestinationChangedListener
为 navController 定义一个。使用它按需加载每个工具栏。
活动.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ryvod)
// Set up AppBar
appBarLayout = findViewById(R.id.appbar)
appBarConfiguration = AppBarConfiguration(setOf(R.id.StartFragment))
defaultToolbar = layoutInflater.inflate(R.layout.toolbar_default, appBarLayout, false) as MaterialToolbar
toolbar2 = layoutInflater.inflate(R.layout.toolbar2, appBarLayout, false) as MaterialToolbar
val host =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment?
?: return
val navController = host.navController
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.locationPickerFragment -> {
appBarLayout.removeAllViews()
appBarLayout.addView(toolbar2)
setSupportActionBar(toolbar2)
}
else -> {
appBarLayout.removeAllViews()
appBarLayout.addView(defaultToolbar)
setSupportActionBar(defaultToolbar)
}
}
setupActionBarWithNavController(navController, appBarConfiguration)
}
}
这应该够了吧