web-dev-qa-db-fra.com

Comportement de mise en page personnalisée de la mise en page du coordinateur jamais appelé

Tout d'abord, je voudrais faire précéder cela de mon manque de connaissances sur la disposition du coordinateur. Je ne fais que suivre des tutoriels que j'ai trouvés en ligne et je suis curieux de savoir pourquoi mon comportement ne fonctionne pas.

La vue enfant à l'intérieur de la disposition du coordinateur doit-elle être une disposition de la barre d'application? Ou êtes-vous capable de mettre n'importe quelle vue à l'intérieur.

De plus, lorsque je définis l'espace de noms res-auto, cela ne me donne pas l'option pour layout_behavior. Habituellement Android studio se complétera automatiquement si une fonction est disponible et ce n'est pas le cas. Bien que, si je tape layout_behavior, cela ne se plaindra pas. Alors peut-être que ça marche ...?

Quoi qu'il en soit, j'ai défini mon propre comportement de mise en page personnalisée et j'essaie de l'appliquer, mais cela ne semble pas fonctionner. Toute idée serait grandement apprécié.

Voici la mise en page. J'essaie d'appliquer mon comportement personnalisé au premier LinearLayout (search_polls_toolbar) et de le faire défiler vers le haut lorsque la vue de recyclage verticale défile vers le haut. (Comme la barre d'outils le fait actuellement.) Je dois également mentionner que ce xml est destiné à un fragment dans un viewpager. Et l'activité d'hébergement a une disposition de coordinateur qui fait que la barre d'outils défile vers le haut. (Pourrait-il être en conflit à cause de cela?)

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

Et voici le comportement personnalisé:

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;
    }
}

Et voici la disposition des activités d'hébergement.

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

Si quelqu'un souhaite que je poste plus de mon code, faites-le moi savoir! Merci :)

23
cj1098

La raison pour laquelle cela ne fonctionne pas est que la vue avec Behavior doit être un enfant direct de CoordinatorLayout. Dans votre cas, la hiérarchie est: CoordinatorLayout -> RelativeLayout -> LinearLayout (avec Behavior).

73
Dmitry Zaytsev

J'ai une disposition comme celle-ci. Il y a quelques choses situées dans les régions supérieures, mais le fond ne contient qu'un FAB qui est profondément imbriqué.

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

Le FAB est profondément imbriqué.

CoordinatorLayout > ConstraintLayout > RelativeLayout > FABProgressCircle > FAB

Cependant, le RelativeLayout doit être poussé vers le haut par le CoordinatorLayout lorsque le Snackbar est affiché.

Le comportement qui le fera est aussi simple que suit.

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;
    }
}

Affichez le Snackbar comme ceci.

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

onDependentViewRemoved doit être remplacé, car lors de la suppression manuelle d'un Snackbar, le CoordinatorLayout ne déclenchera pas le déplacement du View traduit (le FloatingActionButton et son RelativeLayout) à sa place d'origine. En remplaçant la méthode, nous pouvons la traduire à l'endroit où elle se trouvait.

3
Kohányi Róbert