'app:layout_behavior'应该在哪里设置?

Where should 'app:layout_behavior' be set?

它应该设置在 AppBarLayout 同级的父级还是在其同级内的第一个可滚动视图?


Material Design for Android, there are Views that let us work with the behavior of the layout depending on its surroundings, one of them is the CoordinatorLayout, as this CodePath guide 提及:

CoordinatorLayout extends the ability to accomplish many of the Google's Material Design scrolling effects. Currently, there are several ways provided in this framework that allow it to work without needing to write your own custom animation code.

我现在感兴趣的是:

  • Expanding or contracting the Toolbar or header space to make room for the main content.

因此,我们将使用 AppBarLayoutToolbar 设置 app:layout_scrollFlags 和另一个 ViewGroup 兄弟使用 app:layout_behavior.

AppBarLayout

我的问题是:我们应该把它放在哪个 ViewGroup(或者可能是 View)中 app:layout_behavior?


到目前为止,我已经尝试过(它们都有效,而且它们都是 AppBarLayout 的兄弟姐妹):

这个没用:


网上有多个例子,但其中 none 确实说明了你应该把它放在哪里,比如:

http://www.ingloriousmind.com/blog/quick-look-on-the-coordinatorlayout/ https://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout https://developer.android.com/training/basics/firstapp/building-ui.html https://www.bignerdranch.com/blog/becoming-material-with-android-design-support-library/

检查这个 link: https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

AppBarLayout also requires a separate scrolling sibling in order to know when to scroll. The binding is done through the AppBarLayout.ScrollingViewBehavior class, meaning that you should set your scrolling view's behavior to be an instance of AppBarLayout.ScrollingViewBehavior. A string resource containing the full class name is available.

他们提到过,应该是 View 会显示在 AppBarLayout 下,像这样:

<android.support.design.widget.CoordinatorLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

     <android.support.v4.widget.NestedScrollView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             app:layout_behavior="@string/appbar_scrolling_view_behavior">

         <!-- Your scrolling content -->

     </android.support.v4.widget.NestedScrollView>

     <android.support.design.widget.AppBarLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent">

         <android.support.v7.widget.Toolbar
                 ...
                 app:layout_scrollFlags="scroll|enterAlways"/>

         <android.support.design.widget.TabLayout
                 ...
                 app:layout_scrollFlags="scroll|enterAlways"/>

     </android.support.design.widget.AppBarLayout>

 </android.support.design.widget.CoordinatorLayout>

My question is: in what exact ViewGroup (or maybe View) should we put that app:layout_behavior?

在这个 link 中:http://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout

Next, we need to define an association between the AppBarLayout and the View that will be scrolled. Add an app:layout_behavior to a RecyclerView or any other View capable of nested scrolling such as NestedScrollView. The support library contains a special string resource @string/appbar_scrolling_view_behavior that maps to AppBarLayout.ScrollingViewBehavior, which is used to notify the AppBarLayout when scroll events occur on this particular view. The behavior must be established on the view that triggers the event.

app:layout_behavior 应设置为协调器布局的直接子视图

确保您在 String.xml

中添加了 appbar_scrolling_view_behavior 字段
<!-- The class name to the ScrollingChildBehavior required for AppBarLayout -->
<string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>

众所周知,我们可以像下面这样使用它

<android.support.v7.widget.RecyclerView
        android:id="@+id/rvSomeList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

仅供参考,并非 OP 答案。

我必须将以下内容添加到 gradle 文件中,否则会出现编译错误。

implementation 'com.google.android.material:material:1.0.0'

希望这对其他人也有帮助!

对于将 CoordinatorLayoutFragmentContainerAppBarLayout 一起使用的人:

  • 在容器上也设置 app:layout_behavior 真的很好(不仅仅是在 NestedScrollViewRecyclerView 上)。它删除了 FragmentContainer 不必要的底部边距,并保证在显示键盘时应用栏隐藏。

AppBarLayout also requires a separate scrolling sibling in order to know when to scroll.

来自 Android 的描述非常不完整,浪费了我几个小时的时间。

滚动同级用词不当,不需要是任何类型的滚动视图。

例如,在我的 AppBarLayout 下方,我使用的 ViewPager2 将呈现 Fragment,而 Fragment 将呈现 Scrollview,因此我需要设置app:layout_behavior="@string/appbar_scrolling_view_behavior" 直接在主布局中的 ViewPager2 上,NOT 片段布局中的深层嵌套 Scrollview

我也没有用在屏幕上或屏幕外滚动 AppBarLayout 或其任何子项,所以我错误地认为我可以在任何地方不设置 app:layout_behavior

错了。

这揭示了一个更隐蔽的问题:AppBarLayout 需要 滚动兄弟,是的。但不是 只是 来“知道何时滚动”,而是实际调整兄弟姐妹的大小以使其与屏幕一起正确显示!否则,兄弟会保持其配置的大小,并会被 AppBarLayout!您甚至可以在 Android Studio 的布局编辑器中看到这一点。

长话短说:如果您要使用 AppBarLayout,您 需要 app:layout_behavior="@string/appbar_scrolling_view_behavior" 标记您的一个视图,无论它是是否有滚动视图。