Karussell mit MotionLayout

Carousel ist ein Motion-Hilfsobjekt zum Erstellen benutzerdefinierter Karussell-Ansichten, die eine Liste von Elementen enthalten, die der Nutzer überfliegen kann. Im Vergleich zu anderen Möglichkeiten zum Implementieren solcher Ansichten können Sie mit diesem Hilfsprogramm schnell komplexe Bewegungs- und Dimensionsänderungen für Carousel vornehmen, indem Sie MotionLayout nutzen.

Das Carousel-Widget unterstützt Listen mit einem Start- und Endpunkt sowie kreisförmige Umbruchlisten.

Funktionsweise von Carousel mit MotionLayout

Angenommen, Sie möchten eine horizontale Carousel-Ansicht erstellen, in der das Element in der Mitte vergrößert ist:

Dieses grundlegende Layout enthält mehrere Ansichten, die die Carousel-Elemente darstellen:

Erstellen Sie einen MotionLayout mit den folgenden drei Status und weisen Sie ihnen IDs zu:

  • Zurück
  • starten
  • Weiter

Wenn der Status start dem Basislayout entspricht, werden die Carousel-Elemente im Zustand previous und im Status next um eins nach links bzw. nach rechts verschoben.

Angenommen, die fünf Ansichten in Abbildung 3 nehmen an, dass im start-Status die Ansichten B, C und D sichtbar sind und dass A und E sich außerhalb des Bildschirms befinden. Richten Sie den vorherigen Status so ein, dass sich die Positionen von A, B, C und D an den Positionen B, C, D und E befinden, wobei die Ansichten von links nach rechts bewegt werden. Im nächsten muss das Gegenteil geschehen, wobei B, C, D und E sich dorthin bewegen, wo A, B, C und D waren, und die Ansichten von rechts nach links verlaufen. Das ist in Abbildung 4 dargestellt:

Es ist wichtig, dass die Aufrufe genau dort landen, wo die ursprünglichen Aufrufe beginnen. Carousel erzeugt den Anschein einer unendlichen Sammlung von Elementen, indem die tatsächlichen Ansichten wieder an den ursprünglichen Ort verschoben, aber mit dem neuen übereinstimmenden Inhalt neu initialisiert werden. Das folgende Diagramm zeigt diesen Mechanismus. Achten Sie auf die Werte von „item #“):

Übergänge

Wenn Sie diese drei Einschränkungssätze in der Bewegungsszenendatei definiert haben, erstellen Sie zwei Übergänge (vorwärts und rückwärts) zwischen den Status start und next und den Status start und previous. Fügen Sie einen OnSwipe-Handler hinzu, der die Übergänge als Reaktion auf eine Geste auslöst, wie im folgenden Beispiel gezeigt:

    <Transition
        motion:constraintSetStart="@id/start"
        motion:constraintSetEnd="@+id/next"
        motion:duration="1000"
        android:id="@+id/forward">
        <OnSwipe
            motion:dragDirection="dragLeft"
            motion:touchAnchorSide="left" />
    </Transition>

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/previous"
        android:id="@+id/backward">
        <OnSwipe
            motion:dragDirection="dragRight"
            motion:touchAnchorSide="right" />
    </Transition>

Nach dem Erstellen dieser grundlegenden Bewegungsszene fügen Sie dem Layout einen Carousel-Hilfsprogramm hinzu und verweisen auf die Ansichten in der Reihenfolge, in der Sie Ihre vorherige und nächste Animation implementieren.

Legen Sie die folgenden Attribute für den Helper Carousel fest:

  • app:carousel_firstView: die Ansicht, die das erste Element des Carousel darstellt – in diesem Beispiel C.
  • app:carousel_previousState: die ConstraintSet-ID des vorherigen Status.
  • app:carousel_nextState: die ConstraintSet-ID des nächsten Bundesstaats.
  • app:carousel_backwardTransition: die Transition-ID, die zwischen dem Start- und dem vorherigen Status angewendet wird.
  • app:carousel_forwardTransition: Die Transition-ID, die zwischen den Status start und next angewendet wird.

Ihre Layout-XML-Datei könnte beispielsweise Folgendes enthalten:

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

        <ImageView  android:id="@+id/imageView0" .. />
        <ImageView  android:id="@+id/imageView1" .. />
        <ImageView  android:id="@+id/imageView2" .. />
        <ImageView  android:id="@+id/imageView3" .. />
        <ImageView  android:id="@+id/imageView4" .. />

        <androidx.constraintlayout.helper.widget.Carousel
            android:id="@+id/carousel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:carousel_forwardTransition="@+id/forward"
            app:carousel_backwardTransition="@+id/backward"
            app:carousel_previousState="@+id/previous"
            app:carousel_nextState="@+id/next"
            app:carousel_infinite="true"
            app:carousel_firstView="@+id/imageView2"
            app:constraint_referenced_ids="imageView0,imageView1,imageView2,imageView3,imageView4" />

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

Richten Sie einen Carousel-Adapter im Code ein:

Kotlin

carousel.setAdapter(object : Carousel.Adapter {
            override fun count(): Int {
              // Return the number of items in the Carousel.
            }

            override fun populate(view: View, index: Int) {
                // Implement this to populate the view at the given index.
            }

            override fun onNewItem(index: Int) {
                // Called when an item is set.
            }
        })

Java

carousel.setAdapter(new Carousel.Adapter() {
            @Override
            public int count() {
                // Return the number of items in the Carousel.
            }

            @Override
            public void populate(View view, int index) {
                // Populate the view at the given index.
            }

            @Override
            public void onNewItem(int index) {
                 // Called when an item is set.
            }
        });

Zusätzliche Anmerkungen

Abhängig vom aktuell ausgewählten Element in Carousel müssen die Ansichten, in denen die Elemente davor oder danach dargestellt werden, möglicherweise ausgeblendet werden, um die Carousel start und end korrekt zu berücksichtigen. Das Carousel-Hilfsprogramm erledigt dies automatisch. Standardmäßig werden die Ansichten in diesen Situationen als View.INVISIBLE gekennzeichnet, sodass sich das Gesamtlayout nicht ändert.

Ein alternativer Modus ist verfügbar, in dem das Hilfsprogramm Carousel diese Ansichten stattdessen als View.GONE markiert. Sie können diesen Modus mit dem folgenden Attribut festlegen:

app:carousel_emptyViewsBehavior="gone"

Beispiele

Weitere Beispiele für die Verwendung des Carousel-Hilfsprogramms finden Sie in den Beispielprojekten auf GitHub.