MotionLayout
เป็นประเภทเลย์เอาต์ที่ช่วยให้คุณจัดการการเคลื่อนไหวและภาพเคลื่อนไหวของวิดเจ็ตในแอปได้
MotionLayout เป็นคลาสย่อยของ
ConstraintLayout และสร้างขึ้นจากความสามารถด้านเลย์เอาต์ที่หลากหลาย MotionLayout
เป็นไลบรารีสนับสนุนในส่วนของไลบรารี ConstraintLayout
MotionLayout ช่วยลดช่องว่างระหว่างการเปลี่ยนเลย์เอาต์และการจัดการการเคลื่อนไหวที่ซับซ้อน โดยมีฟีเจอร์ต่างๆ ผสมผสานกันระหว่างเฟรมเวิร์กภาพเคลื่อนไหวของพร็อพเพอร์ตี้, TransitionManager และ CoordinatorLayout
นอกเหนือจากการอธิบายการเปลี่ยนเลย์เอาต์แล้ว MotionLayout ยังช่วยให้คุณ
เคลื่อนไหวพร็อพเพอร์ตี้เลย์เอาต์ใดก็ได้ นอกจากนี้ ยังรองรับการเปลี่ยนฉากที่เลื่อนได้โดยค่าเริ่มต้น ซึ่งหมายความว่าคุณสามารถแสดงจุดใดก็ได้ในการเปลี่ยนผ่าน
ตามเงื่อนไขบางอย่าง เช่น การป้อนข้อมูลด้วยการสัมผัส MotionLayout ยังรองรับ
คีย์เฟรม ซึ่งช่วยให้คุณปรับแต่งทรานซิชันได้อย่างเต็มที่ตามความต้องการ
MotionLayout เป็นแบบประกาศทั้งหมด ซึ่งหมายความว่าคุณสามารถอธิบายการเปลี่ยนฉากใดก็ได้ใน XML ไม่ว่าจะซับซ้อนเพียงใดก็ตาม
ข้อควรพิจารณาในการออกแบบ
MotionLayout มีไว้เพื่อย้าย ปรับขนาด และทำให้องค์ประกอบ UI ที่ผู้ใช้โต้ตอบด้วยเคลื่อนไหว เช่น ปุ่มและแถบชื่อ อย่าใช้การเคลื่อนไหวในแอปเป็น
เอฟเฟกต์พิเศษที่ไม่จำเป็น ใช้เพื่อช่วยให้ผู้ใช้เข้าใจสิ่งที่แอปของคุณ
กำลังทำ ดูข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบแอปด้วยการเคลื่อนไหวได้ที่ส่วน Material Design ทำความเข้าใจ
การเคลื่อนไหว
เริ่มต้นใช้งาน
ทำตามขั้นตอนต่อไปนี้เพื่อเริ่มใช้ MotionLayout ในโปรเจ็กต์
-
เพิ่มทรัพยากร Dependency
ConstraintLayout: หากต้องการใช้MotionLayoutในโปรเจ็กต์ ให้เพิ่ม ทรัพยากร DependencyConstraintLayout2.0 ลงในไฟล์build.gradleของแอป หากคุณใช้ AndroidX ให้เพิ่มทรัพยากร Dependency ต่อไปนี้ดึงดูด
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.1" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.1") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1") }
-
สร้างไฟล์
MotionLayout:MotionLayoutเป็นคลาสย่อยของConstraintLayoutคุณจึงแปลงConstraintLayoutที่มีอยู่ เป็นMotionLayoutได้โดย แทนที่ชื่อคลาสในไฟล์ทรัพยากรเลย์เอาต์ ดังที่แสดงใน ตัวอย่างต่อไปนี้AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
ไลบรารีการสนับสนุน
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
ต่อไปนี้คือตัวอย่างแบบเต็มของไฟล์
MotionLayoutซึ่ง กำหนดเลย์เอาต์ที่แสดงในรูปที่ 1AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>
ไลบรารีการสนับสนุน
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
-
สร้าง MotionScene: ใน
MotionLayoutตัวอย่างก่อนหน้า แอตทริบิวต์app:layoutDescriptionอ้างอิงถึง MotionScene ฉากเคลื่อนไหวคือไฟล์ทรัพยากร XML ภายในองค์ประกอบรูทของ<MotionScene>ฉากการเคลื่อนไหวจะมีคำอธิบายการเคลื่อนไหวทั้งหมดสำหรับเลย์เอาต์ที่ เกี่ยวข้อง แต่ละMotionLayoutจะอ้างอิงฉากการเคลื่อนไหว แยกต่างหาก เพื่อแยกข้อมูลเลย์เอาต์ออกจากคำอธิบาย การเคลื่อนไหว คำจำกัดความในฉากการเคลื่อนไหวจะมีความสำคัญเหนือกว่าคำจำกัดความที่คล้ายกันในMotionLayoutต่อไปนี้คือตัวอย่างไฟล์ฉากการเคลื่อนไหวที่อธิบายการเคลื่อนไหวแนวนอนพื้นฐาน ในรูปที่ 1
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>
ข้อควรทราบ
-
<Transition>มีคำจำกัดความพื้นฐานของการเคลื่อนไหว-
motion:constraintSetStartและmotion:constraintSetEndเป็นการอ้างอิงถึง จุดสิ้นสุดของการเคลื่อนไหว ปลายทางเหล่านี้กำหนดไว้ใน องค์ประกอบ<ConstraintSet>ในภายหลังในฉากการเคลื่อนไหว -
motion:durationระบุจำนวนมิลลิวินาที ที่ใช้ในการเคลื่อนไหวให้เสร็จสมบูรณ์
-
-
<OnSwipe>ช่วยให้คุณสร้างการควบคุมด้วยการสัมผัสสำหรับการเคลื่อนไหวได้-
motion:touchAnchorIdหมายถึงมุมมองที่ผู้ใช้สามารถ ปัดและลากได้ -
motion:touchAnchorSideหมายความว่า กำลังลากมุมมองจากด้านขวา -
motion:dragDirectionหมายถึงความคืบหน้า ทิศทางการลาก เช่นmotion:dragDirection="dragRight"หมายถึงความคืบหน้า จะเพิ่มขึ้นเมื่อลากมุมมองไปทางขวา
-
-
<ConstraintSet>คือที่ที่คุณกำหนดข้อจำกัดต่างๆ ที่อธิบายการเคลื่อนไหว ในตัวอย่างนี้ มีการกำหนด<ConstraintSet>1 รายการสำหรับ แต่ละจุดสิ้นสุดของการเคลื่อนไหว ปลายทางเหล่านี้อยู่ตรงกลางในแนวตั้ง โดยใช้app:layout_constraintTop_toTopOf="parent"และapp:layout_constraintBottom_toBottomOf="parent"ในแนวนอน จุดสิ้นสุดจะอยู่ทางด้านซ้ายและขวาสุดของหน้าจอ
ดูรายละเอียดเพิ่มเติมเกี่ยวกับองค์ประกอบต่างๆ ที่ฉากเคลื่อนไหวรองรับได้ที่ตัวอย่าง MotionLayout
-
แอตทริบิวต์ที่ประมาณค่า
ภายในไฟล์ฉากเคลื่อนไหว องค์ประกอบ ConstraintSet สามารถมีแอตทริบิวต์เพิ่มเติม
ซึ่งจะได้รับการประมาณค่าระหว่างการเปลี่ยนฉาก นอกจากตำแหน่งและขอบเขตแล้ว MotionLayout ยังประมาณค่าแอตทริบิวต์ต่อไปนี้ด้วย
alphavisibilityelevationrotation,rotationX,rotationYtranslationX,translationY,translationZscaleX,scaleY
แอตทริบิวต์ที่กำหนดเอง
ภายใน <Constraint> คุณสามารถใช้องค์ประกอบ <CustomAttribute> เพื่อระบุ
การเปลี่ยนสำหรับแอตทริบิวต์ที่ไม่ได้เกี่ยวข้องกับตำแหน่งหรือแอตทริบิวต์ View
เพียงอย่างเดียว
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
<CustomAttribute> มีแอตทริบิวต์ของตัวเอง 2 รายการ ได้แก่
motion:attributeNameต้องระบุและต้องตรงกับออบเจ็กต์ที่มีเมธอด Getter และ Setter Getter และ Setter ต้องตรงกับรูปแบบที่เฉพาะเจาะจง ตัวอย่างเช่น ระบบรองรับbackgroundColorเนื่องจากมุมมองมีเมธอดgetBackgroundColor()และsetBackgroundColor()ที่เกี่ยวข้อง- แอตทริบิวต์อื่นๆ ที่คุณต้องระบุจะขึ้นอยู่กับประเภทค่า เลือกจากประเภทที่รองรับต่อไปนี้
motion:customColorValueสำหรับสีmotion:customIntegerValueสำหรับจำนวนเต็มmotion:customFloatValueสำหรับการลอยmotion:customStringValueสำหรับสตริงmotion:customDimensionสำหรับมิติข้อมูลmotion:customBooleanสำหรับบูลีน
เมื่อระบุแอตทริบิวต์ที่กำหนดเอง ให้กำหนดค่าปลายทางทั้งในองค์ประกอบเริ่มต้นและองค์ประกอบสิ้นสุด <ConstraintSet>
เปลี่ยนสีพื้นหลัง
จากตัวอย่างก่อนหน้า สมมติว่าคุณต้องการให้สีของวิวเปลี่ยน เป็นส่วนหนึ่งของการเคลื่อนไหว ดังที่แสดงในรูปที่ 2
เพิ่มองค์ประกอบ <CustomAttribute> ลงในองค์ประกอบ ConstraintSet แต่ละรายการ ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
<ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#9999FF" /> </Constraint> </ConstraintSet>
แอตทริบิวต์ MotionLayout เพิ่มเติม
นอกจากแอตทริบิวต์ในตัวอย่างก่อนหน้าแล้ว MotionLayout ยังมีแอตทริบิวต์อื่นๆ
ที่คุณอาจต้องการระบุด้วย
app:applyMotionScene="boolean"ระบุว่าจะใช้ฉากเคลื่อนไหวหรือไม่ ค่าเริ่มต้นสำหรับแอตทริบิวต์นี้คือtrueapp:showPaths="boolean"ระบุว่าจะแสดงเส้นทางการเคลื่อนไหวขณะที่ การเคลื่อนไหวทำงานอยู่หรือไม่ ค่าเริ่มต้นสำหรับแอตทริบิวต์นี้คือfalseapp:progress="float"ช่วยให้คุณระบุความคืบหน้าของการเปลี่ยนฉากได้อย่างชัดเจน คุณ สามารถใช้ค่าจุดลอยตัวใดก็ได้ตั้งแต่0(จุดเริ่มต้นของการเปลี่ยนผ่าน) ไปจนถึง1(จุดสิ้นสุดของการเปลี่ยนผ่าน)app:currentState="reference"ช่วยให้คุณระบุConstraintSetที่เฉพาะเจาะจงได้app:motionDebugช่วยให้คุณแสดงข้อมูลการแก้ไขข้อบกพร่องเพิ่มเติมเกี่ยวกับ การเคลื่อนไหวได้ ค่าที่เป็นไปได้คือ"SHOW_PROGRESS","SHOW_PATH"หรือ"SHOW_ALL"
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับ MotionLayout ได้ที่แหล่งข้อมูลต่อไปนี้
- Android ขั้นสูงใน Kotlin 03.2: ภาพเคลื่อนไหวด้วย MotionLayout
- ตัวอย่าง MotionLayout
- ตัวอย่าง MotionLayout/ConstraintLayout ใน GitHub
- ข้อมูลเบื้องต้นเกี่ยวกับ MotionLayout (ตอนที่ 1)
- ข้อมูลเบื้องต้นเกี่ยวกับ MotionLayout (ตอนที่ 2)
- ข้อมูลเบื้องต้นเกี่ยวกับ MotionLayout (ตอนที่ 3)
- ข้อมูลเบื้องต้นเกี่ยวกับ MotionLayout (ตอนที่ 4)