可以仅将CoordinatorLayout行为应用于CoordinatorLayout的直接子级吗?

时间:2018-07-19 23:09:20

标签: android android-coordinatorlayout

根据我到目前为止的读物,Behavior仅适用于CoordinatorLayout的直接子级。但是以下代码使我感到困惑:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".ScrollingActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="@android:color/holo_red_light"
            app:layout_scrollFlags="scroll"
            app:toolbarId="@+id/toolbar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="parallax"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

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


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v4.widget.NestedScrollView
            android:id="@+id/nestedScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            tools:context=".ScrollingActivity"
            tools:showIn="@layout/activity_scrolling">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="@string/large_text" />

        </android.support.v4.widget.NestedScrollView>
    </FrameLayout>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test Button"
        android:visibility="visible"
        android:layout_gravity="bottom"
        app:layout_anchor="@id/nestedScrollView"
        app:layout_behavior="am.i.coord.CustomBehavior"
        />

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

NestedScrollView不是CoordinatorLayout的直接子代(被包装在FrameLayout中),但是仍然应用了Behavior,可以正确触发AppBarLayout中的更改。

与自定义Button在同一级别添加的behavior仅在将其设为CoordinatorLayout的直接子级时才有效。如果我将它作为FrameLayout的同级对象移到NestedScrollView内,则不会执行任何回调。

为什么会有这种区别? 如果Behavior不打算由CoordinatorLayout's的非直接子级使用,是否有另一种方式可以在NestedScrollView中滚动更改时通知非直接子级? / strong>我只能考虑向CoordinatorLayout添加一个虚拟视图,该视图将向间接子级发出滚动事件,但这会使代码混乱。

1 个答案:

答案 0 :(得分:4)

是的,行为必须附加到CoordinatorLayout的直接子级上。 Intercepting everything with CoordinatorLayout blog post中详细说明了为什么它适用于NestedScrollView

  

嵌套滚动不仅可以源自CoordinatorLayout的直接子级,还可以源自任何子视图(例如CoordinatorLayout的子级的子级)

这是嵌套滚动本身的独立属性,而不是CoordinatorLayout独有的属性:嵌套滚动事件通过每个父级ViewGroup沿视图层次结构传播。这就是CoordinatorLayout获得对这些事件的访问权限的方式,并且“行为”使CoordinatorLayout能够将这些事件分配给其他孩子,而不是直接在滚动视图的视图层次结构中。

您推测,如果希望间接子级知道滚动更改,则即使它是虚拟视图,也必须具有CoordinatorLayout的直接子级。当然,您可以创建CoordinatorLayout的子类,并可以挂接到相同的事件流中,因为all of the methods可以被覆盖。