Carosello con MotionLayout

Prova Compose
Jetpack Compose è il toolkit per la UI consigliato per Android. Scopri come aggiungere un carosello in Crea.

Carousel è un oggetto helper di movimento per creare visualizzazioni personalizzate del carosello che mostrano un elenco di elementi che l'utente può sfogliare. Rispetto ad altri modi per implementare queste visualizzazioni, questo helper ti consente di creare rapidamente modifiche complesse di movimento e dimensioni per il tuo Carousel sfruttando MotionLayout.

Il widget Carousel supporta elenchi con un inizio e una fine, nonché elenchi circolari a capo.

Come funziona la funzionalità Carosello con MotionLayout

Supponiamo di voler creare una visualizzazione orizzontale Carousel con l'elemento centrale ingrandito:

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

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

  • precedente
  • start
  • Avanti

Se lo stato start corrisponde al layout di base, nello stato previous e nello stato next gli elementi Carousel vengono spostati di uno verso sinistra e verso destra, rispettivamente.

Ad esempio, prendi le cinque visualizzazioni nella figura 3 e supponi che nello stato start le visualizzazioni B, C e D siano visibili e che A ed E siano fuori dallo schermo. Imposta lo stato precedente in modo che le posizioni di A, B, C e D corrispondano a quelle di B, C, D ed E, con le visualizzazioni che si spostano da sinistra a destra. Nello stato successivo, deve avvenire il contrario: B, C, D ed E si spostano dove si trovavano A, B, C e D, mentre le visualizzazioni si spostano da destra a sinistra. Ciò è mostrato nella figura 4:

È fondamentale che le visualizzazioni finiscano esattamente dove iniziano le visualizzazioni originali. Carousel dà l'illusione di una raccolta infinita di elementi spostando le visualizzazioni effettive nella posizione precedente, ma reinizializzandole con i nuovi contenuti corrispondenti. Il seguente diagramma mostra questo meccanismo. Presta attenzione ai valori "item #"):

Transizioni

Con questi tre set di vincoli definiti nel file della scena di movimento, crea due transizioni, una in avanti e una indietro, tra gli stati start e next e tra gli stati start e previous. Aggiungi un gestore OnSwipe per attivare le transizioni in risposta a un gesto, come mostrato nell'esempio seguente:

    <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 l'animazione precedente e successiva.

Imposta i seguenti attributi per l'helper Carousel:

  • app:carousel_firstView: la visualizzazione che rappresenta il primo elemento di Carousel, in questo esempio C.
  • app:carousel_previousState: l'ID ConstraintSet dello stato precedente.
  • app:carousel_nextState: l'ID ConstraintSet dello stato successivo.
  • app:carousel_backwardTransition: l'ID Transition applicato tra lo stato iniziale e quello precedente.
  • app:carousel_forwardTransition: l'ID Transition applicato tra lo stato iniziale e quello successivo.

Ad esempio, nel file XML di layout hai 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

A seconda dell'elemento corrente "selezionato" in Carousel, le visualizzazioni che rappresentano gli elementi precedenti o successivi potrebbero dover essere nascoste per tenere conto correttamente dell'inizio e della fine di Carousel. L'helper Carousel gestisce questa operazione automaticamente. Per impostazione predefinita, in queste situazioni le visualizzazioni vengono contrassegnate come View.INVISIBLE, in modo che il layout generale non cambi.

È disponibile una modalità alternativa in cui l'helper Carousel contrassegna le visualizzazioni 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 i progetti di esempio su GitHub.