1

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

我已经设置了 MainActivity,如文档中所示:LinearLayout 作为父视图,在 AppBarLayout 内,在 CollapsingToolbarLayout 内,以及工具栏本身。和宿主片段。

导航起始目的地是一个 FrameLayout,其中包含实际的 RecyclerView。

我尝试了各种 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 时工具栏会折叠。实际上它只是静态的。

我认为 RecyclerView 和 CollapsingToolbar 之间可能有联系吗?我错过了什么?

4

2 回答 2

1

谢谢你,你是我的救星。我最近也在为此苦苦挣扎,所以我对您的解决方案进行了更多尝试,并且得出了一些结论(撰写时间 2019-08-08):

TL;DR CollapsingToolbarLayout 也可以工作,但片段大小不正确。

  1. 顶层布局必须是 CoordinatorLayout,因为如果它不是任何东西都可以协调 AppBarLayout 和片段。
  2. <fragment>元素必须具有 属性app:layout_behavior="@string/appbar_scrolling_view_behavior"。似乎 CoordinatorLayout 仅在其直接子级中搜索以查找行为。
  3. AppBarLayout//层次结构其实很好CollapsingToolbarLayoutToolbar只要<fragment>app:layout_behavior属性,这也可以正常工作。
  4. 片段内的布局并不重要。就我而言,使用视图模型,这意味着我需要一个额外的<layout>包装器,所以我都尝试了

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

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

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

  5. 这种安排不会正确调整片段的大小。如果您还向片段添加了 FloatingActionButton,则它无法正常与 FrameLayout 一起使用(尽管 FAB 在左上角app:layout_anchorGravity="bottom|right|end")。

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

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

如果有人有任何建议或指点,请发表评论。我希望有一天能真正做到这一点。

于 2019-08-08T07:43:15.113 回答
0

找到了解决方案。

使用 CoordinatorLayout 作为父视图而不是 LinearLayout。删除 CollapsingToolbarLayout。在工具栏中声明layout_scrollFlags(例如 app:layout_scrollFlags="scroll|enterAlways|snap")。并在片段视图中添加app:layout_behavior="@string/appbar_scrolling_view_behavior"(很重要,因为我们在家庭片段中使用了 RecyclerView)

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>

MainActivity onCreate

    // 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)
于 2019-07-15T15:47:37.120 回答