ภาพสไลด์ที่มี MotionLayout

ลองใช้วิธีแบบ Compose
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีเพิ่มภาพหมุนใน Compose

Carousel เป็นออบเจ็กต์ตัวช่วยด้านการเคลื่อนไหวสำหรับสร้างมุมมองภาพหมุนที่กำหนดเอง ซึ่งแสดงรายการองค์ประกอบที่ผู้ใช้สามารถดูคร่าวๆ ได้ ตัวช่วยนี้ช่วยให้คุณสร้างการเคลื่อนไหวที่ซับซ้อนและการเปลี่ยนแปลงขนาด สำหรับ Carousel ได้อย่างรวดเร็วโดยใช้ประโยชน์จาก MotionLayout เมื่อเทียบกับวิธีอื่นๆ ในการใช้มุมมองดังกล่าว

วิดเจ็ต Carousel รองรับรายการที่มีจุดเริ่มต้นและจุดสิ้นสุด รวมถึงรายการแบบวนซ้ำ

วิธีทำงานของ Carousel กับ MotionLayout

สมมติว่าคุณต้องการสร้างมุมมอง Carousel แนวนอนโดยให้รายการตรงกลางขยายใหญ่ขึ้น

เลย์เอาต์พื้นฐานนี้มีมุมมองหลายรายการที่แสดงถึงรายการ Carousel

สร้าง MotionLayout ที่มี 3 สถานะต่อไปนี้และกำหนดรหัสให้

  • previous
  • start
  • next

หากสถานะ start สอดคล้องกับเลย์เอาต์พื้นฐาน ในสถานะ previous และสถานะ next รายการ Carousel จะเลื่อนไปทางซ้ายและขวาอย่างละ 1 รายการตามลำดับ

ตัวอย่างเช่น ให้ใช้มุมมอง 5 รายการในรูปที่ 3 และสมมติว่าในสถานะ start มุมมอง B, C และ D จะมองเห็นได้ ส่วน A และ E จะอยู่นอกหน้าจอ ตั้งค่าสถานะ previous เพื่อให้ตำแหน่งของ A, B, C และ D อยู่ในตำแหน่งที่ B, C, D และ E เคยอยู่ โดยมุมมองจะเลื่อนจากซ้ายไปขวา ในสถานะ next จะต้องเกิดเหตุการณ์ตรงกันข้าม โดย B, C, D และ E จะย้ายไปอยู่ในตำแหน่งที่ A, B, C และ D เคยอยู่ และมุมมองจะเลื่อนจากขวาไปซ้าย ดังแสดงในรูปที่ 4

สิ่งสำคัญคือมุมมองจะต้องสิ้นสุดในตำแหน่งที่มุมมองเดิมเริ่มต้น Carousel สร้างภาพลวงตาของคอลเล็กชันองค์ประกอบที่ไม่มีที่สิ้นสุดโดยการย้ายมุมมอง จริง กลับไปยังตำแหน่งเดิม แต่เริ่มต้นใหม่ด้วยเนื้อหาที่ตรงกัน แผนภาพต่อไปนี้แสดงกลไกนี้ โปรดสังเกตค่า "item #"

การเปลี่ยนภาพ

เมื่อกำหนดชุดข้อจำกัด 3 ชุดนี้ในไฟล์ฉากการเคลื่อนไหวแล้ว ให้สร้างการเปลี่ยนภาพ 2 รายการ ได้แก่ ไปข้างหน้าและย้อนกลับ ระหว่างสถานะ start กับ next และสถานะ start กับ previous เพิ่มตัวแฮนเดิล OnSwipe เพื่อ ทริกเกอร์การเปลี่ยนภาพเพื่อตอบสนองต่อท่าทางสัมผัส ดังที่แสดงในตัวอย่าง ต่อไปนี้

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

หลังจากสร้างฉากการเคลื่อนไหวพื้นฐานนี้แล้ว ให้เพิ่มตัวช่วย Carousel ลงในเลย์เอาต์และอ้างอิงมุมมองตามลำดับเดียวกับที่คุณใช้ภาพเคลื่อนไหวก่อนหน้าและถัดไป

ตั้งค่าแอตทริบิวต์ต่อไปนี้สำหรับตัวช่วย Carousel

  • app:carousel_firstView: มุมมองที่แสดงถึงองค์ประกอบแรกของ Carousel ซึ่งในตัวอย่างนี้คือ C
  • app:carousel_previousState: รหัส ConstraintSet ของสถานะ previous
  • app:carousel_nextState: รหัส ConstraintSet ของสถานะ next
  • app:carousel_backwardTransition: รหัส Transition ที่ใช้ระหว่างสถานะ start กับ previous
  • app:carousel_forwardTransition: รหัส Transition ที่ใช้ระหว่างสถานะ start กับ next

ตัวอย่างเช่น คุณมีโค้ดลักษณะนี้ในไฟล์ XML ของเลย์เอาต์

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

ตั้งค่าตัวปรับ 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.
            }
        });

หมายเหตุเพิ่มเติม

มุมมองที่แสดงถึงรายการก่อนหน้าหรือถัดไปอาจต้องซ่อนไว้เพื่อให้บัญชี Carousel start และ end ถูกต้อง ทั้งนี้ขึ้นอยู่กับรายการปัจจุบันที่ "เลือก" ใน Carousel ตัวช่วย Carousel จะจัดการเรื่องนี้โดยอัตโนมัติ โดยค่าเริ่มต้น ระบบจะทำเครื่องหมายมุมมองเหล่านั้นเป็น View.INVISIBLE ในสถานการณ์เหล่านี้ เพื่อไม่ให้เลย์เอาต์โดยรวมเปลี่ยนแปลง

นอกจากนี้ยังมีโหมดอื่นที่ตัวช่วย Carousel จะทำเครื่องหมายมุมมองเหล่านั้นเป็น View.GONE แทน คุณสามารถตั้งค่าโหมดนี้ได้โดยใช้พร็อพเพอร์ตี้ต่อไปนี้

app:carousel_emptyViewsBehavior="gone"

ตัวอย่าง

ดูตัวอย่างเพิ่มเติมที่ใช้ตัวช่วย Carousel ได้ใน โปรเจ็กต์ตัวอย่าง ใน GitHub