问题描述
根据我到目前为止的读物,行为
只能应用于 CoordinatorLayout
的直接子级.但是以下代码使我感到困惑:
Based on my reading so far, Behavior
can only be applied to direct children of CoordinatorLayout
. But the following code is confusing me:
<?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中的更改.
The NestedScrollView
is not a direct child of CoordinatorLayout
(being wrapped in a FrameLayout), but still has a Behavior
applied, which is properly triggering changes in AppBarLayout.
与自定义行为
在同一级别添加的 Button
仅在将其设为 CoordinatorLayout
的直接子代时才有效.如果我将其作为 NestedScrollView
的同级对象移到 FrameLayout
内,则不会执行任何回调.
The Button
I added at the same level with a custom behavior
is working only if I make it a direct child of CoordinatorLayout
. If I move it inside the FrameLayout
as a sibling of NestedScrollView
, then none of the callbacks are executed.
为什么会有这种区别?如果行为
并非由 CoordinatorLayout的
非直接子级使用,是否有另一种方式可以在 NestedScrollView
??我只能想到在 CoordinatorLayout
中添加一个虚拟视图,该视图将向间接子级发出滚动事件,但会使代码混乱.
Why this difference? If Behavior
is not meant to be used by CoordinatorLayout's
non-direct children, is there another way for the non-direct children to be notified on scroll changes in NestedScrollView
? I can only think of adding a dummy view to the CoordinatorLayout
which will emit scroll events to indirect children, but it makes the code messy.
推荐答案
是的,必须将行为附加到 CoordinatorLayout
的直接子代中.NestedScrollView .nofollow noreferrer>使用CoordinatorLayout博客文章拦截所有内容,其中指出:
Yes, behaviors must be attached to the direct children of a CoordinatorLayout
. Why it works for NestedScrollView
is detailed in the Intercepting everything with CoordinatorLayout blog post, which states:
这是嵌套滚动本身的一个单独属性,而不是 CoordinatorLayout
所独有的:嵌套滚动事件通过每个父级 ViewGroup
沿视图层次结构传播.这是 CoordinatorLayout
获取这些事件的方式,并且Behaviors允许 CoordinatorLayout
将这些事件分派给其他孩子,而不是直接在滚动视图的视图层次结构中.
This is a separate property of nested scrolling itself, not something unique to CoordinatorLayout
: nested scrolling events propagate up the view hierarchy through each parent ViewGroup
. This is how CoordinatorLayout
gains access to those events and Behaviors are what allows CoordinatorLayout
to dispatch those events to other children not directly in the view hierarchy of the scrolling view.
如您所料,如果您希望间接子级知道滚动更改,则即使它是虚拟视图,也必须具有 CoordinatorLayout
的直接子级.当然,如果您想作为所有方法都可以被覆盖.
As you surmised, if you want an indirect child to be aware of scroll changes, you must have a direct child of CoordinatorLayout
, even if it is a dummy view. You can, of course, create a subclass of CoordinatorLayout
and hook into the same event stream if you want as all of the methods can be overridden.
这篇关于可以仅将CoordinatorLayout行为应用于CoordinatorLayout的直接子级吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!