Carousel dengan MotionLayout

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

Widget Carousel mendukung daftar dengan awal dan akhir serta lingkaran {i>wrap-around list<i}.

Cara kerja Carousel dengan MotionLayout

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

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

Buat MotionLayout dengan tiga status berikut dan beri ID tersebut:

  • sebelumnya
  • mulai
  • berikutnya

Jika status start sesuai dengan tata letak dasar, dalam status sebelumnya dan status next, item Carousel digeser satu ke kiri dan di sebelah kanan.

Misalnya, ambil lima tampilan pada gambar 3 dan asumsikan bahwa pada awal status, tampilan B, C, dan D terlihat, serta A dan E berada di luar layar. Setel naik ke status sebelumnya sehingga posisi A, B, C, dan D berada di tempat B, C, D, dan E adalah, dengan tampilan bergerak dari kiri ke kanan. Dalam video berikutnya maka hal yang sebaliknya harus terjadi, di mana B, C, D, dan E bergerak ke A, B, C, dan D adalah, dan tampilan bergerak dari kanan ke kiri. Hal ini ditunjukkan dalam gambar 4:

Penayangan harus berakhir tepat di tempat penayangan aslinya dimulai. Carousel memberikan ilusi kumpulan elemen yang tak terbatas dengan memindahkan tampilan sebenarnya kembali ke tempat sebelumnya, tetapi melakukan inisialisasi ulang dengan konten pencocokan baru. Diagram berikut menunjukkan mekanisme ini. Bayar memperhatikan "item #" ):

Transisi

Dengan tiga set batasan yang ditentukan dalam file adegan gerakan Anda, buat dua transisi—maju dan mundur—antara awal dan berikutnya status serta status start dan previous. Tambahkan Pengendali OnSwipe ke memicu transisi sebagai respons terhadap suatu {i>gesture, <i}seperti yang ditunjukkan contoh:

    <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 scene gerakan dasar ini dibuat, tambahkan helper Carousel ke tata letak dan mereferensikan tampilan dalam urutan yang sama dengan yang Anda implementasikan sebelumnya dan berikutnya animasi.

Tetapkan atribut berikut untuk helper Carousel:

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

Misalnya, Anda memiliki kode seperti ini di 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 "dipilih" saat ini di Carousel, tampilan yang mewakili item sebelum atau sesudah mungkin perlu disembunyikan agar memperhitungkan start dan end Carousel. Tuas bantuan Carousel hal ini secara otomatis. Secara default, tampilan tersebut akan ditandai sebagai View.INVISIBLE di situasi ini, sehingga tata letak secara keseluruhan tidak berubah.

Tersedia mode alternatif yang menandai helper Carousel tampilan tersebut sebagai View.GONE. Anda dapat menetapkan mode ini menggunakan properti berikut:

app:carousel_emptyViewsBehavior="gone"

Contoh

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