“app:layout_behavior” 应该在哪里设置?

43

它应该设置在AppBarLayout兄弟节点的父节点上还是在其兄弟节点内部的第一个可滚动视图中?


使用Material Design for Android,我们可以使用Views来根据布局周围的情况处理布局行为,其中之一是CoordinatorLayout,正如this CodePath guide所述:

CoordinatorLayout扩展了许多Google的Material Design滚动效果的功能。目前,在此框架中提供了几种方法,使其能够在不需要编写自己的自定义动画代码的情况下工作。

我现在感兴趣的是:
  • 展开或收缩工具栏或标题空间以为主要内容腾出空间。

因此,我们将使用AppBarLayout和一个Toolbar,并设置app:layout_scrollFlags,另外还需要将另一个ViewGroup兄弟节点放置到AppBarLayout中,并设置app:layout_behavior

我的问题是:我们应该将app:layout_behavior放在哪个确切的{{ViewGroup}}(或者可能是{{View}})中呢?


到目前为止,我已经尝试过以下几种方式(它们都有效,并且都是AppBarLayout的兄弟节点):
  • 滚动视图

  • 可滚动视图中的第一个ViewGroup

  • ViewGroup内部包含ScrollView

但这种方式不起作用:

  • 没有可滚动视图子项的ViewGroup。

网络上有很多例子,但是它们没有真正说明应该把它放在哪里,例如:

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/

6个回答

32

请查看此链接:https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

AppBarLayout还需要一个单独的滚动兄弟来判断何时滚动。通过 AppBarLayout.ScrollingViewBehavior 类进行绑定,这意味着您应该将滚动视图的行为设置为 AppBarLayout.ScrollingViewBehavior 的实例。可用包含完整类名称的字符串资源。

他们提到,应该是那个显示在 AppBarLayout 下方的 View

<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>

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

并且在这个链接中:http://guides.codepath.com/android/Handling-Scrolls-with-CoordinatorLayout

接下来,我们需要定义一个关联AppBarLayout将要被滚动的View之间。在一个RecyclerView或任何其他支持嵌套滚动的View上添加一个app:layout_behavior,比如NestedScrollView。支持库包含一个特殊的字符串资源@string/appbar_scrolling_view_behavior它映射到AppBarLayout.ScrollingViewBehavior,用于通知AppBarLayout当特定视图上发生滚动事件时。行为必须在触发事件的视图上建立。


2
“支持嵌套滚动的视图”很重要,如果在RecyclerView上禁用了nestedScrolling,则它将无法正常工作。 - Jemshit Iskenderov
1
@Jemshit Iskenderov 是正确的,永远不要设置 recyclerView.setNestedScrollingEnabled(false); 你只是在 AppBarLayout 后使用 recycler,或者你的 RecyclerView 不在 NestedScrollView 中。 - Surjit Singh

20

请确保您在 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" />

这只是提供信息,而不是正式答案。


10
设计支持库已经定义了这个字符串资源。在你自己的资源中重新定义它并没有任何好处,不如直接使用设计支持库中的资源。 - Ted Hopp
1
也许你是对的。我忘了,但是我遇到了问题,在string.xml中添加后解决了它。 - Ranjit

11

app:layout_behavior 应该设置在那些是 Coordinator layout 的直接子视图上。


1
协调者布局实际上是什么?请不要介意,我对Android开发还有点新。 - eRaisedToX
1
@eRaisedToX 这只是一个带有一些附加功能的FrameLayout。请检查一下https://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html - Ranjit
同时还有 SwipeRefreshLayout。 - btraas

7
AppBarLayout还需要一个单独的滚动兄弟来知道何时滚动。
这个Android的描述非常不完整,让我浪费了好几个小时的时间。
“Scrolling sibling(滚动兄弟)”是一个错误的称呼,不必是任何类型的滚动视图。
例如,在我的AppBarLayout下面,我使用了一个ViewPager2,它将呈现一个Fragment,该Fragment将呈现一个ScrollView,因此我需要在主布局上直接设置 "app:layout_behavior = "@string/appbar_scrolling_view_behavior" “,而不是深度嵌套的Fragment布局中的ScrollView。
我也没有用于在屏幕上打开或关闭AppBarLayout或其任何子项的滚动,因此我错误地认为我可以不在任何地方设置app:layout_behavior。
错了。
这揭示了一个更阴险的问题:AppBarLayout需要滚动兄弟,是的。但不仅仅是“知道何时滚动”,而是实际调整兄弟的大小,以适当地与其一起占据屏幕!否则,兄弟将保持其配置的大小,并且将被AppBarLayout的高度向下推出屏幕!您甚至可以在Android Studio的布局编辑器中看到这一点。
长话短说:如果要使用AppBarLayout,则需要将其中一个视图标记为app:layout_behavior =" @string/appbar_scrolling_view_behavior",无论它是滚动视图还是其他类型的视图。

3

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

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

希望这也能帮助其他人!

3

对于使用 CoordinatorLayoutFragmentContainerAppBarLayout 的人:

  • 在容器上设置app:layout_behavior也非常好(不仅仅是在NestedScrollViewRecyclerView上设置)。这将删除FragmentContainer的不必要底部边距,并确保当键盘显示时,应用栏(AppBar)会隐藏。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接