MotionLayout
เป็นเลย์เอาต์ประเภทหนึ่งที่ช่วยคุณจัดการการเคลื่อนไหวและภาพเคลื่อนไหววิดเจ็ตในแอป MotionLayout
เป็นคลาสย่อยของ ConstraintLayout
และต่อยอดจากความสามารถของเลย์เอาต์ที่หลากหลาย เนื่องจากเป็นส่วนหนึ่งของไลบรารี ConstraintLayout
MotionLayout
พร้อมให้บริการเป็นไลบรารีการสนับสนุน
MotionLayout
เป็นตัวเชื่อมระหว่างการเปลี่ยนเลย์เอาต์กับการจัดการการเคลื่อนไหวที่ซับซ้อน โดยนำเสนอฟีเจอร์ที่ผสมผสานระหว่างเฟรมเวิร์กภาพเคลื่อนไหวของพร็อพเพอร์ตี้, TransitionManager
และ CoordinatorLayout
นอกเหนือจากการอธิบายการเปลี่ยนระหว่างเลย์เอาต์แล้ว MotionLayout
ยังช่วยให้คุณทำให้คุณสมบัติของเลย์เอาต์เคลื่อนไหวได้ด้วย นอกจากนี้ รูปแบบนี้ยังรองรับทรานซิชันที่กรอได้อยู่แล้ว ซึ่งหมายความว่าคุณสามารถแสดงจุดใดก็ได้ภายในทรานซิชันโดยอิงตามเงื่อนไขบางอย่าง เช่น อินพุตการสัมผัส MotionLayout
ยังรองรับเฟรมหลักด้วย ซึ่งช่วยให้คุณปรับแต่งทรานซิชันได้ตามต้องการ
MotionLayout
เป็นคำสั่งแบบสมบูรณ์ ซึ่งหมายความว่าคุณสามารถอธิบายการเปลี่ยนผ่านใน XML ได้อย่างซับซ้อนเพียงใดก็ได้
ข้อควรพิจารณาเกี่ยวกับการออกแบบ
MotionLayout
มีไว้เพื่อย้าย ปรับขนาด และทำให้องค์ประกอบ UI เคลื่อนไหวที่ผู้ใช้โต้ตอบด้วย เช่น ปุ่มและแถบชื่อ อย่าใช้ภาพเคลื่อนไหวในแอปเป็นเอฟเฟกต์พิเศษที่ไม่จำเป็น ใช้ข้อมูลนี้เพื่อช่วยให้ผู้ใช้เข้าใจว่าแอปของคุณ
กำลังทำอะไรอยู่ ดูข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบแอปด้วยการเคลื่อนไหวได้ที่ส่วนการทำความเข้าใจการเคลื่อนไหวใน Material Design
เริ่มต้นใช้งาน
ทำตามขั้นตอนต่อไปนี้เพื่อเริ่มใช้ MotionLayout
ในโปรเจ็กต์
-
เพิ่ม Dependency
ConstraintLayout
: หากต้องการใช้MotionLayout
ในโปรเจ็กต์ ให้เพิ่ม DependencyConstraintLayout
2.0 ลงในไฟล์build.gradle
ของแอป หากคุณใช้ AndroidX ให้เพิ่มข้อกําหนดต่อไปนี้ดึงดูด
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01") }
-
สร้างไฟล์
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
อ้างอิงฉากการเคลื่อนไหว ฉากการเคลื่อนไหวคือไฟล์ทรัพยากร 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
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,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"
ระบุว่าจะใช้ฉากที่มีการเคลื่อนไหวหรือไม่ ค่าเริ่มต้นสำหรับแอตทริบิวต์นี้คือtrue
app:showPaths="boolean"
ระบุว่าจะแสดงเส้นทางการเคลื่อนไหวขณะที่การเคลื่อนไหวทำงานอยู่หรือไม่ ค่าเริ่มต้นสำหรับแอตทริบิวต์นี้คือfalse
app: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)