11 votes

Est-il possible d'utiliser une mise en page de mouvement avec différentes transitions ?

J'essaie d'afficher une vue à différents endroits en fonction du bouton sur lequel on a cliqué. Mais MotionScene ne fonctionne pas lorsque j'en utilise deux.

<MotionScene xmlns:motion="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
>

<Transition android:id="@+id/toTimePicker2"
motion:duration="500" motion:constraintSetStart="@layout/add_event_fragment" 
 motion:constraintSetEnd="@id/enableTimePicker2">
<OnClick motion:target="@+id/time_to" motion:mode="toggle"/>
</Transition>

<Transition android:id="@+id/toTimePicker1"
motion:constraintSetStart="@layout/add_event_fragment" 
motion:constraintSetEnd="@id/enableTimePicker1"
motion:duration="500">
<OnClick motion:target="@+id/time_from"
  motion:mode="toggle" />
 < /Transition >

Quelqu'un a-t-il une idée de la manière de l'implémenter avec Motion Layout ? Il semble que je doive utiliser ConstraintSet dans le code, mais je veux juste savoir si cela est possible avec Motion ou non.

18voto

odiggity Points 1009

Après des heures et des heures à essayer différentes choses, j'ai finalement trouvé pourquoi ça ne marchait pas pour moi. Je savais que cela devait être possible parce que google fournit un échantillon qui a de multiples transitions https://github.com/googlesamples/Android-ConstraintLayoutExamples/blob/multi_state/motionlayout/src/main/res/xml/scene_26.xml . Mais peu importe ce que j'essayais, seule la première transition du fichier xml fonctionnait. Ce que j'ai finalement réalisé, c'est que pour qu'une transition fonctionne, l'état actuel de l'interface utilisateur doit correspondre à l'état de début ou de fin de la transition tel que défini dans l'ensemble de contraintes. De plus, le même ensemble de contraintes ne peut pas être défini plus d'une fois, ce qui signifie que si vous avez deux transitions différentes qui peuvent se produire sur l'écran initial, les deux transitions doivent partager l'ensemble de contraintes.

J'ai créé un exemple simple de deux boutons qui se déplacent avec des traductions différentes. Je n'ai trouvé aucun exemple simple de ce type nulle part, alors j'espère que cela pourra aider certaines personnes. Comme vous le verrez dans la vidéo, lorsque le bouton left to right Le texte s'est déplacé vers la droite, mais vous ne pouvez pas déplacer l'icône de l'écran. top to bottom en bas de page parce que cet état n'a pas été défini dans une transition.

Enfin, le dernier problème que j'ai rencontré est que chaque ensemble de contraintes semble devoir contenir toutes les vues qui font partie d'une transition, qu'elles soient ou non dans la transition actuelle. Sinon, les vues semblent se déplacer au hasard.

enter image description here

Voici la mise en page :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_main"
        app:layoutDescription="@xml/motion_scene"
        tools:context=".MainActivity">

    <TextView
            android:id="@+id/left_to_right_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Left to right"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

    <TextView
            android:id="@+id/top_to_bottom_text"
            android:text="Top to bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.motion.widget.MotionLayout>

Et voici le MotionScene

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition
            app:constraintSetStart="@id/base"
            app:constraintSetEnd="@id/bottom">
        <OnClick
                app:targetId="@id/top_to_bottom_text">

        </OnClick>

    </Transition>

    <Transition
            app:constraintSetStart="@id/base"
            app:constraintSetEnd="@id/right">
        <OnClick
                app:targetId="@id/left_to_right_text">

        </OnClick>

    </Transition>

    <ConstraintSet android:id="@+id/base">

        <Constraint
                android:id="@id/left_to_right_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <Constraint
                android:id="@id/top_to_bottom_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/bottom">

        <Constraint
                android:id="@id/left_to_right_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <Constraint
                android:id="@id/top_to_bottom_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
        />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/right">

        <Constraint
                android:id="@id/left_to_right_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <Constraint
                android:id="@id/top_to_bottom_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>
    </ConstraintSet>
</MotionScene>

6voto

teh_raab Points 232

Juste retour sur l'Android Dev Summit d'hier Motion Layout States sera supporté dans l'Alpha 3.

Regardez cette vidéo L'ensemble de la vidéo vaut la peine d'être regardée, mais les états de Motion Layout sont mentionnés à 36:50 dans la vidéo alors qu'ils mentionnent ConstraintLayout Alpha 3.

6voto

alisonthemonster Points 117

Google fait ce commentaire sur son Blogue du médium des développeurs de Google :

Remarque : il est possible de définir plusieurs ConstraintSets dans un MotionScene, donc si vous avez un mouvement à plusieurs étapes où ces étapes sont des états de " repos " valides, vous pouvez les utiliser à la place des images clés. La transition d'un état à l'autre doit être effectuée dans le code (des écouteurs de changement sont disponibles).

J'ai donc pu le faire en créant un auditeur :

motion_layout.setTransitionListener(
    object : MotionLayout.TransitionListener {
        override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
        }

        override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
            if (currentId == R.id.two) {
                //if the 1st transition has been made go to the second one
                intro_motion_layout.setTransition(R.id.two, R.id.three)
                intro_motion_layout.transitionToEnd()
            }
        }
    }
)
intro_motion_layout.transitionToEnd()

Et puis dans mon MotionScene j'avais trois transitions :

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">

<Transition
    motion:constraintSetStart="@+id/one"
    motion:constraintSetEnd="@+id/two"
    motion:duration="200"
    motion:interpolator="linear" />

<ConstraintSet android:id="@+id/one">
    <Constraint />
</ConstraintSet>

<ConstraintSet android:id="@+id/two">
    <Constraint />
</ConstraintSet>

<ConstraintSet android:id="@+id/three">
    <Constraint />
</ConstraintSet>

0voto

Rishabh Sharma Points 1

J'ai été confronté à un problème similaire dans lequel j'avais défini 2 transitions : A -> B (que nous appellerons transition X) B -> C (appelée transition Y) toutes deux déclenchées en cliquant sur la vue animée.

C'est l'ordre des transitions dans le fichier de la scène de mouvement qui importait dans mon cas. La transition définie en premier est exécutée en premier. Ainsi, si la transition Y était définie au-dessus de la transition X, seules les transitions B -> C -> B étaient possibles. Cependant, en plaçant la transition X au-dessus de la transition Y dans le fichier de scène de mouvement, les transitions suivantes sont devenues possibles : A -> B -> C -> B.

Note : A -> B ne peut toujours être réalisé qu'une seule fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X