如何修复折叠工具栏布局不折叠与回收器视图使用喷气背包导航组件?(导航用户界面)



>我正在使用新的 Jetpack 导航组件和 NavigationUI 类设置应用程序导航,以支持在 CollapsingToolbarLayout 中的导航。 但是,它无法使用文档中的代码/方法。

我已经设置了主活动,如文档所示: 线性布局作为父视图、在 AppBarLayout 中、在 CollapsingToolbarLayout 中以及工具栏本身。和主机片段。

导航开始目的地是 FrameLayout,其中包含实际的回收器视图。

我尝试了各种layout_scrollFlags,并尝试将CoordinatorLayout设置为父视图而不是LinearLayout。

activity_main.xml

<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="top"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"/>
</LinearLayout>

在 MainActivity onCreate 函数中:

// Set Toolbar as ActionBar
setSupportActionBar(findViewById(R.id.toolbar))
val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
layout.setupWithNavController(toolbar, navController, appBarConfiguration)

我期望崩溃行为的第一个目的地:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".restaurant.RestaurantsFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/restaurant_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/restaurant_item"/>
</FrameLayout>

我希望工具栏在滚动浏览回收器视图时折叠。 实际上它只是静态的。

我认为RecyclerView和CollapsingToolbar之间可能缺少连接? 我错过了什么?

谢谢你,你是我的救主。我最近也为此苦苦挣扎,所以我更多地玩弄了你的解决方案,我来了一些 结论(撰写本文时间 2019-08-08):

TL;DR折叠工具栏布局也可以,但片段大小不正确。

  1. 顶级布局必须是 CoordinatorLayout,因为如果不是,则无法协调 AppBarLayout 和片段。
  2. <fragment>元素必须具有属性app:layout_behavior="@string/appbar_scrolling_view_behavior"。似乎 CoordinatorLayout 只在其直接子项中搜索以查找行为。
  3. 实际上,有一个AppBarLayout/CollapsingToolbarLayout/Toolbar层次结构是可以的。只要<fragment>具有app:layout_behavior属性,这将 也可以正常工作。
  4. 片段内的布局并不重要。在我的情况下,使用视图模型,这意味着我需要一个额外的<layout>包装器,所以我尝试了两者

    <layout>
    <data></data>
    <FrameLayout>
    <RecyclerView/>
    <FrameLayout>
    </layout>
    

    <layout>
    <data></data>
    <CoordinatorLayout>
    <RecyclerView/>
    <CoordinatorLayout>
    </layout>
    

    两者都工作正常。内部的 CoordinatorLayout 不会吞噬该行为,因为 RecyclerView 没有或使用行为,但这将我引出了下一点:

  5. 这种安排无法正确调整片段的大小。如果您还向片段添加了浮动操作按钮,则它无法与FrameLayout正常工作(尽管app:layout_anchorGravity="bottom|right|end",FAB仍位于左上角)。

    如果在片段中使用 CoordinatorLayout,就像我上面的第二个示例一样,FAB 会跳转到正确的位置。显示和隐藏不起作用,即使您为自己实现了ScrollAwareFABBehavior。相反,发生的情况是 FAB 在屏幕外滚动,显示片段是视口垂直高度的 100%,但被工具栏的高度向下移动(如果是扩展的 CollapsingToolbarLayout,这可能是 300dp 或几乎屏幕的一半在我的情况下)。

我一直无法找到解决此问题的方法,我将暂时停止尝试。似乎单活动/单工具栏模型还不能处理 CoordinatorLayout 的事情。Android 文档使用 LinearLayout 的原因可能是为了确保片段具有正确的垂直大小,但在此过程中放弃了任何动态行为功能。我可能会使用嵌套的导航图,其中应用程序的每个部分都将包含适当的工具栏。

如果有人有任何建议或指示,请发表评论。我想有一天真正让它工作。

找到了一个解决方案。

使用 CoordinatorLayout 作为父视图,而不是 LinearLayout。 删除折叠工具栏布局。 在工具栏中声明layout_scrollFlags(例如.app:layout_scrollFlags="scroll|enterAlways|snap")。 在片段视图中添加app:layout_behavior="@string/appbar_scrolling_view_behavior">(很重要,因为我们在主页片段中使用回收器视图)

main_activity.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap"
/>
</com.google.android.material.appbar.AppBarLayout>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

主活动创建

// Set Toolbar as ActionBar
setSupportActionBar(findViewById(R.id.toolbar))
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
findViewById<Toolbar>(R.id.toolbar)
.setupWithNavController(navController, appBarConfiguration)

最新更新