【问题标题】:Coordinator layout custom layout behavior never getting called协调器布局自定义布局行为永远不会被调用
【发布时间】:2015-10-22 12:13:03
【问题描述】:

首先,我想以我对协调器布局缺乏了解作为开头。我只是按照我在网上找到的教程进行操作,我很好奇为什么我的行为不起作用。

协调器布局内的子视图是否必须是应用栏布局? 或者你能把任何视图放在那里。

另外,当我定义 res-auto 命名空间时,它没有给我 layout_behavior 的选项。通常,如果一个功能可用而它没有,android studio 会自动完成。虽然,如果我输入 layout_behavior 它不会抱怨。所以也许它正在工作......?

无论如何,我已经定义了自己的自定义布局行为并尝试应用它,但它似乎不起作用。任何见解将不胜感激。

这是布局。我正在尝试将我的自定义行为应用于第一个 LinearLayout (search_polls_toolbar),并在垂直回收视图向上滚动时让它向上滚动。 (就像当前的工具栏一样。) 我还应该提到,这个 xml 是用于 viewpager 中的一个片段。并且宿主活动有一个附加的协调器布局,它确实使工具栏向上滚动。 (会不会因此而产生冲突?)

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/root"
    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">
<RelativeLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <LinearLayout
        android:id="@+id/search_polls_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:actionBarSize"
        android:background="@color/icitizen_toolbar_orange"
        android:weightSum="1"
      app:layout_behavior="com.example.chrisjohnson.icitizenv2.CustomBehaviors.ToolbarBehavior"
        >

        <EditText
            android:id="@+id/search_polls"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:hint="@string/search_polls"
            android:gravity="center_horizontal"
            android:layout_weight=".5"
            android:drawableLeft="@drawable/magnifying_glass"
            android:drawableStart="@drawable/magnifying_glass"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="15dp"
            android:drawablePadding="-50dp"
            android:paddingLeft="5dp"
            android:paddingTop="5dp"
            android:paddingBottom="10dp"
            android:cursorVisible="false"
            android:textSize="20sp"
            android:background="@color/icitizen_light_orange"
            />

    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/poll_horizontal_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="75dp"
        android:layout_below="@id/search_polls_toolbar"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp"
        android:scrollbars="none"
        >

    </android.support.v7.widget.RecyclerView>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/poll_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:layout_below="@id/poll_horizontal_recycler_view"
        app:layout_scrollFlags="scroll|enterAlways"
        android:scrollbars="vertical" />

</RelativeLayout>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/polls_fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/white_plus_icon"
    android:layout_marginBottom="70dp"
    app:backgroundTint="@color/icitizen_orange"
    app:layout_anchor="@id/container"
    app:layout_anchorGravity="bottom|right|end"
    app:borderWidth="0dp"
    android:layout_marginRight="15dp"
    android:layout_marginEnd="15dp"/>

这是自定义行为:

public class ToolbarBehavior extends CoordinatorLayout.Behavior<Toolbar> {
    public ToolbarBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        Toast.makeText(context, "AJSJA", Toast.LENGTH_LONG).show();
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, Toolbar child, View dependency) {
        return dependency instanceof RecyclerView;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, Toolbar child, View dependency) {
        child.setTranslationY(child.getY());
        return true;
    }
}

这是托管活动的布局。

    <?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"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?android:attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            />
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/home_viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        />
</android.support.design.widget.CoordinatorLayout>

如果有人希望我发布我的代码,请告诉我!谢谢:)

【问题讨论】:

    标签: android behavior android-coordinatorlayout


    【解决方案1】:

    它不起作用的原因是Behavior 的视图必须是CoordinatorLayout 的直接子级。在您的情况下,层次结构是:CoordinatorLayout -> RelativeLayout -> LinearLayout(带有Behavior)。

    【讨论】:

    • Google 有时让我哭泣
    • 您好,您知道解决此问题的任何解决方法吗?
    • 这一点解释得很好!
    【解决方案2】:

    我有这样的布局。上面区域有一些东西,但底部只有一个嵌套很深的FAB。

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/your_coordinator_id">
    
        <android.support.constraint.ConstraintLayout
            app:layout_behavior="com.yourpackage.YourBehavior">
    
            <ScrollView>
                ...
            </ScrollView>
    
            <android.support.design.widget.TextInputLayout>
                ...
            </android.support.design.widget.TextInputLayout>
    
            <android.support.design.widget.TextInputLayout>
                ...
            </android.support.design.widget.TextInputLayout>
    
            <!--
                Everything "around" the FAB needs to be moved.
            -->
            <RelativeLayout
                android:id="@+id/your_view_id">
    
               <com.github.jorgecastilloprz.FABProgressCircle>
    
                    <!--
                       This is the actual FAB.
                    -->
                    <android.support.design.widget.FloatingActionButton/>
                </com.github.jorgecastilloprz.FABProgressCircle>
            </RelativeLayout>
        </android.support.constraint.ConstraintLayout>
    </android.support.design.widget.CoordinatorLayout>
    

    FAB 嵌套很深。

    CoordinatorLayout &gt; ConstraintLayout &gt; RelativeLayout &gt; FABProgressCircle &gt; FAB

    但是,当显示Snackbar 时,RelativeLayout 需要被CoordinatorLayout 向上推。

    执行此操作的行为如下所示。

    package com.yourpackage;
    
    ...
    
    public class YourBehavior extends CoordinatorLayout.Behavior<ConstraintLayout> {
    
        public YourBehavior(Context context, AttributeSet attrs) {
        }
    
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, ConstraintLayout child, View dependency) {
            float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight());
            // Note that the RelativeLayout gets translated.
            child.findViewById(R.id.your_view_id).setTranslationY(translationY);
            return true;
        }
    
        @Override
        public void onDependentViewRemoved(CoordinatorLayout parent, ConstraintLayout child, View dependency) {
            child.findViewById(R.id.your_view_id).setTranslationY(0.0f);
        }
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, ConstraintLayout child, View dependency) {
            return dependency instanceof Snackbar.SnackbarLayout;
        }
    }
    

    像这样显示Snackbar

    Snackbar.make(findViewById(R.id.your_coordinator_id), "Message", Snackbar.LENGTH_SHORT).show();
    

    onDependentViewRemoved 需要被覆盖,因为当手动关闭 Snackbar 时,CoordinatorLayout 不会触发将已翻译的 ViewFloatingActionButton 及其 RelativeLayout)移回原来的位置。覆盖该方法,我们可以将其转换回原来的位置。

    【讨论】:

    • 完美运行,你拯救了我的一天:D
    • @Blablablabli 我已经更新了我的 Java 代码 sn-p,您可能对更改感兴趣。
    • 确实,我不知道这个案子必须处理,你是MVP :)
    • @Blablablabli 哈哈,谢谢伙计。有一件事让我很困扰。如果 Snackbar 自动关闭(即用户没有将其滑开),“向下滑动”动画流畅、流畅且没有延迟。但是,如果我使用我提到的“onDependentViewRemoved”修复程序,那么“动画”是刚性的并且在 Snackbars 移除和 FAB 运动的实际开始之间存在延迟。让我知道您是否可以解决后者。可以通过使用view.animator() 应用动画来修复“刚性”动画或缺少动画。
    猜你喜欢
    • 2012-10-14
    • 2016-10-25
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    相关资源
    最近更新 更多