web-dev-qa-db-ja.com

コーディネーターレイアウトのカスタムレイアウト動作が呼び出されない

まず、コーディネーターのレイアウトに関する知識が不足していることを前提にしたいと思います。オンラインで見つけたチュートリアルに従っているだけで、なぜ自分の行動が機能しないのか興味があります。

コーディネーターレイアウト内の子ビューはアプリバーレイアウトである必要がありますか?または、そこに任意のビューを配置できますか。

また、res-auto名前空間を定義すると、layout_behaviorのオプションが提供されません。通常、Androidスタジオは、関数が使用可能かどうかにかかわらず自動補完されます。ただし、layout_behaviorと入力しても問題はありません。

とにかく、私は独自のカスタムレイアウト動作を定義し、それを適用しようとしていますが、動作していないようです。どんな洞察も大歓迎です。

これがレイアウトです。カスタム動作を最初のLinearLayout(search_polls_toolbar)に適用し、垂直リサイクラビューが上にスクロールしたときに上にスクロールするようにしています。 (現在のツールバーのように。)また、このxmlはビューページャーのフラグメント用です。そして、ホスティングアクティビティには、ツールバーを上にスクロールさせるコーディネーターレイアウトがアタッチされています。 (それが原因で競合する可能性がありますか?)

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

誰かが私のコードのこれ以上の投稿を希望する場合は、お知らせください!ありがとう:)

23
cj1098

動作しない理由は、Behaviorを持つビューはCoordinatorLayoutの直接の子でなければならないからです。あなたの場合、階層はCoordinatorLayout-> RelativeLayout-> LinearLayout(with Behavior)です。

73
Dmitry Zaytsev

このようなレイアウトがあります。上部の領域にはいくつかのものがありますが、下部には深くネストされた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 > ConstraintLayout > RelativeLayout > FABProgressCircle > FAB

ただし、RelativeLayoutが表示されている場合は、CoordinatorLayoutSnackbarによってプッシュアップする必要があります。

これを行う動作は次のように簡単です。

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)を元の場所に戻すトリガーになりません。メソッドをオーバーライドすると、元の場所に戻すことができます。

3