Carosello con MotionLayout

Carousel è un oggetto motion helper per creare visualizzazioni carosello personalizzate che mostrano un elenco di elementi che l'utente può scorrere. Rispetto ad altri modi di implementare tali viste, questo helper consente di creare rapidamente modifiche complesse di movimenti e dimensioni per Carousel sfruttando MotionLayout

Il widget Carousel supporta elenchi con un inizio e una fine nonché elenchi elenchi completi.

Come funziona il carosello con Layout Movimento

Supponiamo di voler creare una vista Carousel orizzontale, con l'elemento centrale ingrandita:

Questo layout di base contiene diverse visualizzazioni che rappresentano i Carousel elementi:

Crea un MotionLayout con i seguenti tre stati e assegna loro gli ID:

  • precedente
  • avvia
  • Avanti

Se lo stato start corrisponde al layout di base, nello stato precedente. e next indica che Carousel elementi vengono spostati di uno a sinistra e rispettivamente a destra.

Ad esempio, prendi le cinque visualizzazioni nella Figura 3 e supponiamo che nella fase start le viste B, C e D sono visibili, mentre A ed E sono fuori dallo schermo. Imposta lo stato precedente in modo che le posizioni di A, B, C e D siano dove B, C, D ed E erano e le visualizzazioni si spostavano da sinistra a destra. Nel mese successivo deve accadere il contrario, dove B, C, D ed E si spostano dove A, B, le colonne C e D, mentre le visualizzazioni si spostano da destra a sinistra. Questo è mostrato nella figura 4:

È fondamentale che le visualizzazioni finiscano esattamente dove iniziano quelle originali. Carousel dà l'illusione di una raccolta infinita di elementi riportando le viste effettive dove si trovavano, ma reinizializzandole con i nuovi contenuti corrispondenti. Il seguente diagramma mostra questo meccanismo. Paga attenzione all'elemento "item #" di sicurezza):

Transizioni

Con questi tre insiemi di vincoli definiti nel file della scena di movimento, crea due transizioni (avanti e indietro) tra start e next nonché gli stati start e previous. Aggiungi un OnSwipe per attivare le transizioni in risposta a un gesto, come mostrato di seguito esempio:

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

Dopo aver creato questa scena di movimento di base, aggiungi un helper Carousel al layout e fai riferimento alle visualizzazioni nello stesso ordine in cui implementi la precedente e quella successiva l'animazione.

Imposta i seguenti attributi per l'helper Carousel:

  • app:carousel_firstView: la vista che rappresenta il primo elemento di Carousel: in questo esempio, C.
  • app:carousel_previousState: l'ID ConstraintSet della precedente stato.
  • app:carousel_nextState: l'ID ConstraintSet dello stato successivo.
  • app:carousel_backwardTransition: il valore Transition ID applicato tra lo stato inizio e quello precedente.
  • app:carousel_forwardTransition: l'ID Transition applicato tra gli stati start e next.

Ad esempio, il file XML di layout contiene qualcosa di simile a questo:

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

Configura un adattatore Carousel nel codice:

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

Note aggiuntive

In base all'elemento corrente "selezionato" nel Carousel, le viste che rappresentano gli elementi prima o dopo, potrebbero dover essere nascosti account per i valori start e end di Carousel. L'helper Carousel gestisce automaticamente. Per impostazione predefinita, contrassegna queste visualizzazioni come View.INVISIBLE in situazioni in cui il layout generale non cambia.

È disponibile una modalità alternativa in cui l'helper Carousel contrassegna invece quelle viste come View.GONE. Puoi impostare questa modalità utilizzando la seguente proprietà:

app:carousel_emptyViewsBehavior="gone"

Esempi

Per altri esempi di utilizzo dell'helper Carosello, consulta la progetti di esempio su GitHub.