在导航组件中隐藏工具栏或底部导航栏
Posted
技术标签:
【中文标题】在导航组件中隐藏工具栏或底部导航栏【英文标题】:Hiding toolbar or bottomNavigationBar in Navigation Component 【发布时间】:2020-10-08 10:47:28 【问题描述】:我关注guide from android.developers 并在我的应用程序中实现了navigation component
。
当我需要一些屏幕带有或不带有工具栏/底部导航栏时,我偶然发现了一个问题。
Android 开发者示例的布局
<androidx.appcompat.widget.Toolbar
.../>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_
android:layout_
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
.../>
强制我在 MainActivity 的 OnDestinationChanged
回调中隐藏/显示工具栏/bottomNavBar:
navController.addOnDestinationChangedListener _, destination, _ ->
when (destination)
R.id.topLevelDestination->
toolbar.visibility = View.GONE
bottomNav.visibility = View.VISIBLE
R.id.lowLevelDestination ->
toolbar.visibility = View.VISIBLE
bottomNav.visibility = View.GONE
当然,如果我这样做,我会在看到新片段之前调整布局大小。我的意思是我看到了片段 A 上的底部导航是如何消失的,并且当片段 A 仍在屏幕上时,我在底部导航栏所在的位置看到片段的 B 部分,并且在该片段之后,出现了 B。
如何解决?我需要嵌套导航图吗?
更新:添加了问题的 gif 图像
视频说明:它是我屏幕的一部分。在视频中,您可以看到系统 UI、底部导航栏和带有按钮的主要片段。当我单击按钮导航图时,导航图将我导航到 没有 底部导航栏的目的地。所以,我在 OnDestinationChanged 时执行 bottomNavBar.hide()。如您所见,在我实际导航之前,bottomNavBar 消失了,您可以看到在 bottomnavBar 消失后我的目标片段的一部分可见。这就是问题所在。
【问题讨论】:
您可以在每个片段的onStart()
中隐藏/显示工具栏,而不是依赖addOnDestinationChangedListener
。您考虑过这种方法吗?
@azizbekian 是的,我做到了。一样的效果。我的问题是我在 mainactivity_layout 中有 1 个片段容器用于所有片段,有或没有工具栏和底栏。
您可以在 Fragment 和 Activity 之间使用共享 ViewModel,只有一个MutableLiveData<Boolean>
来设置 Toolbar 的可见性,并在 Fragments 的相应生命周期方法 onCreateView、onViewCreated、onStart 或 onResume 中设置它跨度>
@Thracian 实际上,我已经知道一个问题的答案。这是一个嵌套的导航组件图。当您有一个带有工具栏和导航栏的 root_fragment_view 和一个没有时,它们在导航时不会显示/隐藏。没有它,我看不到如何解决问题的方法
不管它是否是嵌套图,您都可以使用 ViewModel 访问这些片段中的任何数据,并在片段的任何生命周期方法中设置它的 liveData 以更改视图的属性。我创建了一些示例,包括 ViewPager 的 NavHostFragment
的子片段的嵌套图,在底部栏的片段内设置当前图的导航或设置 viewpager 的可见性(这个有一些问题)。如果您愿意,可以查看here
【参考方案1】:
我坚持了 2 天,但使用 XML 你可以解决你的问题
-
您需要将工具栏包装到 CoordinatorLayout 中
您的工具栏需要 scrollFlags:滚动并输入
您需要将片段包装在其他层中,并在 layout_behavior 中放入特定行为:@string/appbar_scrolling_view_behavior
在您的 BottomNavigationView 中放置 google 行为:com.google.android.material.behavior.HideBottomViewOnScrollBehavior
类似的东西:
<androidx.coordinatorlayout.widget.CoordinatorLayout
...>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_
android:layout_
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_
android:layout_
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.ActionBar" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_
android:layout_
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment
android:id="@+id/fragment_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_
android:layout_
app:defaultNavHost="true"
app:navGraph="@navigation/graph_main" />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:labelVisibilityMode="unlabeled"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
app:menu="@menu/menu_main" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
顺便说一句,我放置了 NestedScrollView 以使我的所有片段都准备好滚动并在我需要的地方保存其他布局
【讨论】:
那么,它们是如何协同工作的呢?我不明白这将如何成为解决方案 对我来说,该解决方案似乎可行,但有一个主要缺点。我在片段中有一个回收器视图,因此它在滚动视图中扩展片段 -> 生成大量回收器视图不可见,这对性能不利...以上是关于在导航组件中隐藏工具栏或底部导航栏的主要内容,如果未能解决你的问题,请参考以下文章