Karuzela z ruchem

Wypróbuj Compose
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak dodać karuzelę w Compose.

Carousel to obiekt pomocniczy ruchu, który służy do tworzenia niestandardowych widoków karuzeli wyświetlających listę elementów, które użytkownik może przeglądać. W porównaniu z innymi sposobami wdrażania takich widoków ten pomocnik umożliwia szybkie tworzenie złożonych zmian ruchu i wymiarów w przypadku Carousel dzięki wykorzystaniu MotionLayout.

Widżet Carousel obsługuje listy z początkiem i końcem, a także listy cykliczne.

.

Jak działa karuzela z MotionLayout

Załóżmy, że chcesz utworzyć widok poziomy, w którym środkowy element jest powiększony:Carousel

Ten podstawowy układ zawiera kilka widoków reprezentujących elementy Carousel:

Utwórz MotionLayout z tymi 3 stanami i nadaj im identyfikatory:

  • poprzedni
  • start
  • Dalej

Jeśli stan start odpowiada układowi podstawowemu, w stanach previousnext elementy Carousel są przesunięte odpowiednio o jeden w lewo i w prawo.

Weźmy na przykład 5 widoków na rysunku 3 i założmy, że w stanie początkowym widoczne są widoki B, C i D, a widoki A i E znajdują się poza ekranem. Ustaw stan poprzedni tak, aby pozycje A, B, C i D były takie jak pozycje B, C, D i E, a widoki przesuwały się od lewej do prawej. W następnym stanie musi nastąpić odwrotna sytuacja: B, C, D i E przesuwają się w miejsce, w którym były A, B, C i D, a widoki przesuwają się z prawej na lewą stronę. Widać to na rysunku 4:

Konieczne jest, aby wyświetlenia kończyły się dokładnie w miejscu, w którym zaczynają się oryginalne wyświetlenia. Carousel daje iluzję nieskończonej kolekcji elementów, ponieważ rzeczywiste widoki są przesuwane z powrotem na swoje miejsce, ale ponownie inicjowane z nowymi pasującymi treściami. Ten mechanizm przedstawia poniższy diagram. Zwróć uwagę na wartości „item #” (numer elementu):

Przejścia

Po zdefiniowaniu w pliku sceny ruchu tych 3 zbiorów ograniczeń utwórz 2 przejścia – do przodu i do tyłu – między stanami startnext oraz stanami startprevious. Dodaj moduł obsługi OnSwipe, aby wywoływać przejścia w odpowiedzi na gest, jak pokazano w tym przykładzie:

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

Po utworzeniu podstawowej sceny ruchu dodaj do układu Carouselelement pomocniczy i odwołaj się do widoków w tej samej kolejności, w jakiej implementujesz poprzednią i następną animację.

Ustaw te atrybuty dla komponentu Carousel:

  • app:carousel_firstView: widok, który reprezentuje pierwszy element Carousel— w tym przykładzie C.
  • app:carousel_previousState: identyfikator ConstraintSet poprzedniego stanu.
  • app:carousel_nextState: identyfikator ConstraintSet stanu następnego.
  • app:carousel_backwardTransition: identyfikator Transition zastosowany między stanami początkowympoprzednim.
  • app:carousel_forwardTransition: identyfikator Transition zastosowany między stanami początkowymnastępnym.

Na przykład w pliku XML układu masz taki kod:

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

Skonfiguruj w kodzie adapter Carousel:

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

Uwagi dodatkowe

W zależności od aktualnie „wybranego” elementu w Carousel widoki reprezentujące elementy przed lub po nim mogą wymagać ukrycia, aby prawidłowo uwzględnić Carousel początekkoniec. Carousel Pomocnik zajmuje się tym automatycznie. Domyślnie w takich sytuacjach oznacza te widoki jako View.INVISIBLE, dzięki czemu ogólny układ się nie zmienia.

Dostępny jest tryb alternatywny, w którym narzędzie Carousel zamiast tego oznacza widoki jako View.GONE. Ten tryb możesz ustawić za pomocą tej właściwości:

app:carousel_emptyViewsBehavior="gone"

Przykłady

Więcej przykładów użycia narzędzia Carousel znajdziesz w projektach przykładowych w GitHubie.