根据我到目前为止的读物,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
添加一个虚拟视图,该视图将向间接子级发出滚动事件,但这会使代码混乱。
答案 0 :(得分:4)
是的,行为必须附加到CoordinatorLayout
的直接子级上。 Intercepting everything with CoordinatorLayout blog post中详细说明了为什么它适用于NestedScrollView
,
嵌套滚动不仅可以源自CoordinatorLayout的直接子级,还可以源自任何子视图(例如CoordinatorLayout的子级的子级)
这是嵌套滚动本身的独立属性,而不是CoordinatorLayout
独有的属性:嵌套滚动事件通过每个父级ViewGroup
沿视图层次结构传播。这就是CoordinatorLayout
获得对这些事件的访问权限的方式,并且“行为”使CoordinatorLayout
能够将这些事件分配给其他孩子,而不是直接在滚动视图的视图层次结构中。
您推测,如果希望间接子级知道滚动更改,则即使它是虚拟视图,也必须具有CoordinatorLayout
的直接子级。当然,您可以创建CoordinatorLayout
的子类,并可以挂接到相同的事件流中,因为all of the methods可以被覆盖。