Carousel dengan MotionLayout

Coba cara Compose
Jetpack Compose adalah toolkit UI yang direkomendasikan untuk Android. Pelajari cara menambahkan carousel di Compose.

Carousel adalah objek helper gerakan untuk membuat tampilan carousel kustom yang menampilkan daftar elemen yang dapat dilihat sekilas oleh pengguna. Dibandingkan dengan cara lain untuk menerapkan tampilan tersebut, helper ini memungkinkan Anda membuat perubahan dimensi dan gerakan yang kompleks dengan cepat untuk Carousel dengan memanfaatkan MotionLayout.

Widget Carousel mendukung daftar dengan awal dan akhir serta daftar melingkar.

Cara kerja Carousel dengan MotionLayout

Misalnya, Anda ingin membuat tampilan Carousel horizontal, dengan item tengah diperbesar:

Tata letak dasar ini berisi beberapa tampilan yang merepresentasikan item Carousel:

Buat MotionLayout dengan tiga status berikut dan beri ID:

  • sebelumnya
  • start
  • berikutnya

Jika status start sesuai dengan tata letak dasar, dalam status previous dan status next, item Carousel masing-masing digeser satu ke kiri dan ke kanan.

Misalnya, ambil lima tampilan pada gambar 3 dan asumsikan bahwa pada status start, tampilan B, C, dan D terlihat, serta A dan E berada di luar layar. Siapkan status sebelumnya sehingga posisi A, B, C, dan D adalah posisi B, C, D, dan E, dengan tampilan bergerak dari kiri ke kanan. Pada status berikutnya, hal sebaliknya harus terjadi, dengan B, C, D, dan E berpindah ke tempat A, B, C, dan D berada, dan tampilan berpindah dari kanan ke kiri. Hal ini ditunjukkan dalam gambar 4:

Sangat penting agar tampilan berakhir tepat di tempat tampilan asli dimulai. Carousel memberikan ilusi kumpulan elemen tak terbatas dengan memindahkan tampilan aktual kembali ke tempatnya semula, tetapi menginisialisasi ulang tampilan tersebut dengan konten baru yang cocok. Diagram berikut menunjukkan mekanisme ini. Perhatikan nilai "item #"):

Transisi

Dengan tiga set batasan ini yang ditentukan dalam file adegan gerakan, buat dua transisi—maju dan mundur—antara status start dan next serta status start dan previous. Tambahkan pengendali OnSwipe untuk memicu transisi sebagai respons terhadap gestur, seperti yang ditunjukkan dalam contoh berikut:

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

Setelah adegan gerakan dasar ini dibuat, tambahkan Carousel helper ke tata letak dan referensikan tampilan dalam urutan yang sama saat Anda menerapkan animasi sebelumnya dan berikutnya.

Tetapkan atribut berikut untuk helper Carousel:

  • app:carousel_firstView: tampilan yang merepresentasikan elemen pertama Carousel—dalam contoh ini, C.
  • app:carousel_previousState: ID ConstraintSet dari status sebelumnya.
  • app:carousel_nextState: ID ConstraintSet dari status berikutnya.
  • app:carousel_backwardTransition: ID Transition yang diterapkan antara status start dan previous.
  • app:carousel_forwardTransition: ID Transition yang diterapkan di antara status start dan next.

Misalnya, Anda memiliki sesuatu seperti ini dalam file XML tata letak:

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

Siapkan adaptor Carousel dalam kode:

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

Catatan tambahan

Bergantung pada item saat ini yang "dipilih" di Carousel, tampilan yang merepresentasikan item sebelum atau sesudahnya mungkin perlu disembunyikan untuk memperhitungkan awal dan akhir Carousel dengan benar. Pembantu Carousel menangani ini secara otomatis. Secara default, tampilan tersebut ditandai sebagai View.INVISIBLE dalam situasi ini, sehingga tata letak keseluruhan tidak berubah.

Mode alternatif tersedia di mana helper Carousel menandai tampilan tersebut sebagai View.GONE. Anda dapat menyetel mode ini menggunakan properti berikut:

app:carousel_emptyViewsBehavior="gone"

Contoh

Untuk contoh selengkapnya tentang penggunaan helper Carousel, lihat project contoh di GitHub.