เฟรมเวิร์กการเปลี่ยนของ Android ช่วยให้คุณสร้างภาพเคลื่อนไหวการเคลื่อนไหวทุกประเภทใน UI ได้โดยระบุเลย์เอาต์เริ่มต้นและเลย์เอาต์สิ้นสุด คุณเลือกประเภทภาพเคลื่อนไหวที่ต้องการได้ เช่น ให้มุมมองค่อยๆ ปรากฏหรือหายไป หรือเปลี่ยนขนาดมุมมอง และเฟรมเวิร์กการเปลี่ยนจะกำหนดวิธีสร้างภาพเคลื่อนไหวจากเลย์เอาต์เริ่มต้นไปยังเลย์เอาต์สุดท้าย
กรอบการเปลี่ยนผ่านมีฟีเจอร์ต่อไปนี้
- ภาพเคลื่อนไหวระดับกลุ่ม: ใช้เอฟเฟกต์ภาพเคลื่อนไหวกับมุมมองทั้งหมดในลำดับชั้นการแสดงผล
- ภาพเคลื่อนไหวในตัว: ใช้ภาพเคลื่อนไหวที่กำหนดไว้ล่วงหน้าสำหรับเอฟเฟกต์ทั่วไป เช่น การจางออกหรือการเคลื่อนไหว
- การรองรับไฟล์ทรัพยากร: โหลดลําดับชั้นของมุมมองและภาพเคลื่อนไหวในตัวจากไฟล์ทรัพยากรเลย์เอาต์
- Lifecycle Callback: รับ Callback ที่ให้การควบคุมกระบวนการเปลี่ยนภาพเคลื่อนไหวและลำดับชั้น
ดูโค้ดตัวอย่างที่เคลื่อนไหวระหว่างการเปลี่ยนแปลงเลย์เอาต์ได้ที่ BasicTransition
ขั้นตอนพื้นฐานในการเปลี่ยนภาพเคลื่อนไหวระหว่างเลย์เอาต์ 2 แบบมีดังนี้
- สร้างออบเจ็กต์
Sceneสำหรับเลย์เอาต์เริ่มต้นและเลย์เอาต์สิ้นสุด อย่างไรก็ตาม ฉากของเลย์เอาต์เริ่มต้นมักจะกำหนดโดยอัตโนมัติจากเลย์เอาต์ปัจจุบัน - สร้างออบเจ็กต์
Transitionเพื่อกำหนดประเภทภาพเคลื่อนไหวที่ต้องการ - เรียก
TransitionManager.go()และระบบจะเรียกใช้ภาพเคลื่อนไหวเพื่อสลับเลย์เอาต์
แผนภาพในรูปที่ 1 แสดงความสัมพันธ์ระหว่างเลย์เอาต์ ฉาก การเปลี่ยนฉาก และภาพเคลื่อนไหวสุดท้าย
รูปที่ 1 ภาพพื้นฐานของ วิธีที่เฟรมเวิร์กการเปลี่ยนสร้างภาพเคลื่อนไหว
สร้างฉาก
ฉากจะจัดเก็บสถานะของลำดับชั้นของมุมมอง รวมถึงมุมมองทั้งหมดและค่าพร็อพเพอร์ตี้ของมุมมองเหล่านั้น เฟรมเวิร์กการเปลี่ยนฉากสามารถเรียกใช้ภาพเคลื่อนไหวระหว่างฉากเริ่มต้น และฉากสิ้นสุดได้
คุณสร้างฉากจากไฟล์เลย์เอาต์ ทรัพยากรหรือจากกลุ่มมุมมองในโค้ดได้ อย่างไรก็ตาม ระบบมักจะกำหนดฉากเริ่มต้นสำหรับการเปลี่ยนฉากโดยอัตโนมัติจาก UI ปัจจุบัน
นอกจากนี้ ฉากยังกำหนดการกระทำของตัวเองที่จะทำงานเมื่อคุณเปลี่ยนฉากได้ด้วย ฟีเจอร์นี้มีประโยชน์ในการล้างการตั้งค่ามุมมองหลังจาก เปลี่ยนไปใช้ฉาก
สร้างฉากจากทรัพยากรเลย์เอาต์
คุณสร้างSceneอินสแตนซ์ได้โดยตรงจากไฟล์ทรัพยากรเลย์เอาต์
ใช้เทคนิคนี้เมื่อลำดับชั้นของมุมมองในไฟล์ส่วนใหญ่เป็นแบบคงที่
ฉากที่ได้จะแสดงสถานะของลําดับชั้นของมุมมองในเวลาที่คุณสร้างอินสแตนซ์ Scene หากเปลี่ยนลำดับชั้นการแสดงผล ให้สร้างฉากใหม่ เฟรมเวิร์กจะสร้างฉากจากลำดับชั้นมุมมองทั้งหมดในไฟล์ คุณสร้างฉากจากส่วนหนึ่งของไฟล์เลย์เอาต์ไม่ได้
หากต้องการสร้างอินสแตนซ์ Scene จากไฟล์ทรัพยากรเลย์เอาต์ ให้ดึงข้อมูล
รูทฉากจากเลย์เอาต์เป็น ViewGroup จากนั้นเรียกฟังก์ชัน
Scene.getSceneForLayout()
โดยใช้รูทของฉากและรหัสทรัพยากรของไฟล์เลย์เอาต์ที่
มีลำดับชั้นของมุมมองสำหรับฉาก
กำหนดเลย์เอาต์สำหรับฉาก
ข้อมูลโค้ดในส่วนที่เหลือของส่วนนี้แสดงวิธีสร้าง 2 ฉากที่แตกต่างกันโดยใช้องค์ประกอบรากของฉากเดียวกัน
นอกจากนี้ ข้อมูลโค้ดยังแสดงให้เห็นว่าคุณโหลดออบเจ็กต์ Scene ที่ไม่เกี่ยวข้องหลายรายการได้โดยไม่ต้องระบุว่าออบเจ็กต์เหล่านั้นเกี่ยวข้องซึ่งกันและกัน
ตัวอย่างประกอบด้วยคำจำกัดความของเลย์เอาต์ต่อไปนี้
- เลย์เอาต์หลักของกิจกรรมที่มีป้ายกำกับข้อความและองค์ประกอบย่อย
FrameLayout ConstraintLayoutสำหรับฉากแรกที่มีช่องข้อความ 2 ช่องConstraintLayoutสำหรับฉากที่ 2 โดยมีช่องข้อความ 2 ช่องเดียวกันใน ลำดับที่แตกต่างกัน
ตัวอย่างนี้ออกแบบมาเพื่อให้ภาพเคลื่อนไหวทั้งหมดเกิดขึ้นภายในเลย์เอาต์ย่อยของเลย์เอาต์หลักสำหรับกิจกรรม ป้ายกำกับข้อความในเลย์เอาต์หลัก จะยังคงเป็นแบบคงที่
เลย์เอาต์หลักของกิจกรรมมีการกําหนดดังนี้
res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/master_layout"> <TextView android:id="@+id/title" ... android:text="Title"/> <FrameLayout android:id="@+id/scene_root"> <include layout="@layout/a_scene" /> </FrameLayout> </LinearLayout>
คำจำกัดความเลย์เอาต์นี้มีช่องข้อความและองค์ประกอบย่อย FrameLayout สำหรับ
รูทของฉาก เลย์เอาต์สำหรับฉากแรกจะรวมอยู่ในไฟล์เลย์เอาต์หลัก
ซึ่งจะช่วยให้แอปแสดงเป็นส่วนหนึ่งของอินเทอร์เฟซผู้ใช้เริ่มต้นและโหลดลงในฉากได้ เนื่องจากเฟรมเวิร์กจะโหลดได้เฉพาะไฟล์เลย์เอาต์ทั้งไฟล์ลงในฉาก
เลย์เอาต์ของฉากแรกมีการกำหนดดังนี้
res/layout/a_scene.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/text_view1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Text Line 1" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> <TextView android:id="@+id/text_view2" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Text Line 2" app:layout_constraintTop_toBottomOf="@id/text_view1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
เลย์เอาต์ของฉากที่ 2 มีช่องข้อความ 2 ช่องเดียวกัน โดยมีรหัสเดียวกัน แต่จัดเรียงในลำดับที่ต่างกัน โดยมีคำจำกัดความดังนี้
res/layout/another_scene.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/scene_container" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/text_view2" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Text Line 2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <TextView android:id="@+id/text_view1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Text Line 1" app:layout_constraintTop_toBottomOf="@id/text_view2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
สร้างฉากจากเลย์เอาต์
หลังจากสร้างคำจำกัดความสำหรับ ConstraintLayout ทั้ง 2 รายการแล้ว คุณจะรับ ฉากสำหรับแต่ละรายการได้ ซึ่งช่วยให้คุณเปลี่ยนระหว่างการกำหนดค่า UI ทั้ง 2 แบบได้ หากต้องการรับฉาก คุณต้องมีข้อมูลอ้างอิงไปยังรูทของฉากและรหัสทรัพยากรเลย์เอาต์
ข้อมูลโค้ดต่อไปนี้แสดงวิธีรับการอ้างอิงไปยังรูทของฉากและสร้างออบเจ็กต์ Scene 2 รายการจากไฟล์เลย์เอาต์
Kotlin
val sceneRoot: ViewGroup = findViewById(R.id.scene_root) val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this) val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)
Java
Scene aScene; Scene anotherScene; // Create the scene root for the scenes in this app. sceneRoot = (ViewGroup) findViewById(R.id.scene_root); // Create the scenes. aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this); anotherScene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);
ตอนนี้ในแอปมีออบเจ็กต์ Scene 2 รายการตามลำดับชั้นของมุมมอง
ทั้ง 2 ฉากใช้รูทฉากที่กำหนดโดยองค์ประกอบ
FrameLayout ใน res/layout/activity_main.xml
สร้างฉากในโค้ด
นอกจากนี้ คุณยังสร้างSceneอินสแตนซ์ในโค้ดจากออบเจ็กต์ ViewGroup ได้ด้วย ใช้เทคนิคนี้เมื่อคุณแก้ไขลำดับชั้นของมุมมอง
ในโค้ดโดยตรงหรือเมื่อคุณสร้างลำดับชั้นแบบไดนามิก
หากต้องการสร้างฉากจากลำดับชั้นของมุมมองในโค้ด ให้ใช้ตัวสร้าง
Scene(sceneRoot, viewHierarchy)
การเรียกใช้ตัวสร้างนี้เทียบเท่ากับการเรียกใช้ฟังก์ชัน
Scene.getSceneForLayout()
เมื่อคุณขยายไฟล์เลย์เอาต์แล้ว
ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้างอินสแตนซ์ Scene จากองค์ประกอบรูทของฉากและลำดับชั้นการแสดงผลสำหรับฉากในโค้ด
Kotlin
val sceneRoot = someLayoutElement as ViewGroup val viewHierarchy = someOtherLayoutElement as ViewGroup val scene: Scene = Scene(sceneRoot, viewHierarchy)
Java
Scene mScene; // Obtain the scene root element. sceneRoot = (ViewGroup) someLayoutElement; // Obtain the view hierarchy to add as a child of // the scene root when this scene is entered. viewHierarchy = (ViewGroup) someOtherLayoutElement; // Create a scene. mScene = new Scene(sceneRoot, mViewHierarchy);
สร้างการกระทำในฉาก
เฟรมเวิร์กช่วยให้คุณกำหนดการดำเนินการในฉากที่กำหนดเองซึ่งระบบจะเรียกใช้เมื่อ เข้าหรือออกจากฉาก ในหลายกรณี คุณไม่จำเป็นต้องกำหนดการทำงานของฉากที่กำหนดเอง เนื่องจากเฟรมเวิร์กจะสร้างภาพเคลื่อนไหวของการเปลี่ยนแปลงระหว่างฉากโดยอัตโนมัติ
การดำเนินการในฉากมีประโยชน์ในการจัดการกรณีต่อไปนี้
- หากต้องการเคลื่อนไหวมุมมองที่ไม่ได้อยู่ในลำดับชั้นเดียวกัน คุณสามารถทำให้วิวเคลื่อนไหวสำหรับ ฉากเริ่มต้นและฉากจบได้โดยใช้การดำเนินการฉากออกและฉากเข้า
- หากต้องการสร้างภาพเคลื่อนไหวให้กับมุมมองที่เฟรมเวิร์กการเปลี่ยนฉากสร้างภาพเคลื่อนไหวโดยอัตโนมัติไม่ได้
เช่น ออบเจ็กต์
ListViewดูข้อมูลเพิ่มเติมได้ที่ส่วนเกี่ยวกับข้อจำกัด
หากต้องการระบุการดำเนินการในฉากที่กำหนดเอง ให้กำหนดการดำเนินการเป็นออบเจ็กต์ Runnable แล้วส่งไปยังฟังก์ชัน Scene.setExitAction()
หรือ Scene.setEnterAction()
เฟรมเวิร์กจะเรียกใช้ฟังก์ชัน setExitAction() ในฉากเริ่มต้นก่อนที่จะเรียกใช้ภาพเคลื่อนไหวของการเปลี่ยนฉาก และเรียกใช้ฟังก์ชัน setEnterAction() ในฉากสิ้นสุดหลังจากเรียกใช้ภาพเคลื่อนไหวของการเปลี่ยนฉาก
ใช้การเปลี่ยนผ่าน
เฟรมเวิร์กการเปลี่ยนผ่านแสดงถึงรูปแบบของภาพเคลื่อนไหวระหว่างฉากที่มีออบเจ็กต์ Transition คุณสามารถสร้างอินสแตนซ์ของ Transition ได้โดยใช้คลาสย่อยในตัว เช่น AutoTransition และ Fade หรือกำหนดการเปลี่ยนผ่านของคุณเอง
จากนั้นคุณจะเรียกใช้
ภาพเคลื่อนไหวระหว่างฉากได้โดยส่งScene
Transition ไปยัง
TransitionManager.go()
วงจรการเปลี่ยนคล้ายกับวงจรกิจกรรม และแสดงถึง สถานะการเปลี่ยนที่เฟรมเวิร์กตรวจสอบระหว่างจุดเริ่มต้นและ จุดสิ้นสุดของภาพเคลื่อนไหว ในสถานะวงจรที่สำคัญ เฟรมเวิร์กจะเรียกใช้ฟังก์ชันเรียกกลับที่คุณสามารถใช้เพื่อปรับอินเทอร์เฟซผู้ใช้ในระยะต่างๆ ของการเปลี่ยนผ่าน
สร้างการเปลี่ยนฉาก
ส่วนก่อนหน้าแสดงวิธีสร้างฉากที่แสดงสถานะของ
ลำดับชั้นของมุมมองต่างๆ เมื่อกำหนดฉากเริ่มต้นและฉากสิ้นสุดที่ต้องการสลับแล้ว ให้สร้างTransitionออบเจ็กต์ที่กำหนดภาพเคลื่อนไหว
เฟรมเวิร์กช่วยให้คุณระบุการเปลี่ยนฉากในตัวในไฟล์ทรัพยากร
และขยายในโค้ด หรือสร้างอินสแตนซ์ของการเปลี่ยนฉากในตัว
ในโค้ดได้โดยตรง
ตารางที่ 1 ประเภทการเปลี่ยนในตัว
| ชั้น | แท็ก | เอฟเฟ็กต์ |
|---|---|---|
AutoTransition |
<autoTransition/> |
การเปลี่ยนผ่านเริ่มต้น จางออก ย้ายและปรับขนาด รวมถึงจางเข้าในมุมมองตามลำดับ |
ChangeBounds |
<changeBounds/> |
ย้ายและปรับขนาดมุมมอง |
ChangeClipBounds |
<changeClipBounds/> |
จับภาพView.getClipBounds()ก่อนและหลังฉาก
เปลี่ยน และเคลื่อนไหวการเปลี่ยนแปลงเหล่านั้นในระหว่างการเปลี่ยนฉาก |
ChangeImageTransform |
<changeImageTransform/> |
บันทึกเมทริกซ์ของ ImageView ก่อนและหลังการเปลี่ยนฉาก
และเคลื่อนไหวระหว่างการเปลี่ยนฉาก |
ChangeScroll |
<changeScroll/> |
บันทึกพร็อพเพอร์ตี้การเลื่อนของเป้าหมายก่อนและหลังการเปลี่ยนแปลงฉาก และเคลื่อนไหวการเปลี่ยนแปลงใดๆ |
ChangeTransform |
<changeTransform/> |
บันทึกขนาดและการหมุนของมุมมองก่อนและหลังการเปลี่ยนฉาก และเคลื่อนไหวการเปลี่ยนแปลงเหล่านั้นในระหว่างการเปลี่ยนฉาก |
Explode |
<explode/> |
ติดตามการเปลี่ยนแปลงระดับการมองเห็นของมุมมองเป้าหมายในฉากเริ่มต้นและฉากสิ้นสุด และย้ายมุมมองเข้าหรือออกจากขอบของฉาก |
Fade |
<fade/> |
fade_in จะค่อยๆ ปรากฏในมุมมองfade_out จะทำให้มุมมองจางลงfade_in_out (ค่าเริ่มต้น) จะทำ fade_out ตามด้วย
fade_in
|
Slide |
<slide/> |
ติดตามการเปลี่ยนแปลงระดับการมองเห็นของมุมมองเป้าหมายในฉากเริ่มต้นและฉากสิ้นสุด และย้ายมุมมองเข้าหรือออกจากขอบด้านใดด้านหนึ่งของฉาก |
สร้างอินสแตนซ์การเปลี่ยนฉากจากไฟล์ทรัพยากร
เทคนิคนี้ช่วยให้คุณแก้ไขคำจำกัดความของการเปลี่ยนฉากได้โดยไม่ต้องเปลี่ยน โค้ดของกิจกรรม เทคนิคนี้ยังมีประโยชน์ในการแยกคำจำกัดความการเปลี่ยนฉากที่ซับซ้อนออกจากโค้ดแอปพลิเคชันของคุณด้วย ดังที่แสดงในส่วนเกี่ยวกับการระบุการเปลี่ยนฉากหลายรายการ
หากต้องการระบุภาพเคลื่อนไหวในตัวในไฟล์ทรัพยากร ให้ทำตามขั้นตอนต่อไปนี้
- เพิ่มไดเรกทอรี
res/transition/ลงในโปรเจ็กต์ - สร้างไฟล์ทรัพยากร XML ใหม่ภายในไดเรกทอรีนี้
- เพิ่มโหนด XML สำหรับทรานซิชันบิวท์อินรายการใดรายการหนึ่ง
เช่น ไฟล์ทรัพยากรต่อไปนี้จะระบุFadeการเปลี่ยนฉาก
res/transition/fade_transition.xml
<fade xmlns:android="http://schemas.android.com/apk/res/android" />
ข้อมูลโค้ดต่อไปนี้แสดงวิธีขยายอินสแตนซ์ Transition ภายใน
กิจกรรมจากไฟล์ทรัพยากร
Kotlin
var fadeTransition: Transition = TransitionInflater.from(this) .inflateTransition(R.transition.fade_transition)
Java
Transition fadeTransition = TransitionInflater.from(this). inflateTransition(R.transition.fade_transition);
สร้างอินสแตนซ์การเปลี่ยนในโค้ด
เทคนิคนี้มีประโยชน์ในการสร้างออบเจ็กต์การเปลี่ยนฉากแบบไดนามิก หากคุณ แก้ไขอินเทอร์เฟซผู้ใช้ในโค้ด และสร้างอินสแตนซ์การเปลี่ยนฉากในตัวอย่างง่ายๆ ที่มีพารามิเตอร์น้อยหรือไม่มีเลย
หากต้องการสร้างอินสแตนซ์ของการเปลี่ยนฉากในตัว ให้เรียกใช้เครื่องมือสร้างสาธารณะอย่างใดอย่างหนึ่งในคลาสย่อยของคลาส Transition ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้จะสร้างอินสแตนซ์ของการเปลี่ยน Fade
Kotlin
var fadeTransition: Transition = Fade()
Java
Transition fadeTransition = new Fade();
ใช้การเปลี่ยนผ่าน
โดยปกติแล้ว คุณจะใช้การเปลี่ยนผ่านเพื่อสลับระหว่างลำดับชั้นการแสดงผลต่างๆ ในการตอบสนองต่อเหตุการณ์ เช่น การกระทำของผู้ใช้ ตัวอย่างเช่น ลองพิจารณาแอปค้นหา เมื่อผู้ใช้ป้อนคำค้นหาและแตะปุ่มค้นหา แอปจะเปลี่ยน เป็นฉากที่แสดงเลย์เอาต์ผลลัพธ์ขณะใช้การเปลี่ยนฉากที่ ค่อยๆ เลือนปุ่มค้นหาออกและค่อยๆ เลือนผลการค้นหาเข้ามา
หากต้องการเปลี่ยนฉากขณะใช้การเปลี่ยนฉากเพื่อตอบสนองต่อเหตุการณ์ในกิจกรรม ให้เรียกใช้ฟังก์ชันคลาส TransitionManager.go() โดยใช้ฉากสิ้นสุดและอินสแตนซ์การเปลี่ยนฉากที่จะใช้สำหรับภาพเคลื่อนไหว ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
Kotlin
TransitionManager.go(endingScene, fadeTransition)
Java
TransitionManager.go(endingScene, fadeTransition);
เฟรมเวิร์กจะเปลี่ยนลำดับชั้นของมุมมองภายในรูทของฉากด้วยลำดับชั้นของมุมมอง จากฉากสุดท้ายขณะที่เรียกใช้ภาพเคลื่อนไหวที่ระบุโดยอินสแตนซ์การเปลี่ยน ฉากเริ่มต้นคือฉากสิ้นสุดจากการเปลี่ยนผ่านครั้งล่าสุด หากไม่มีการเปลี่ยนผ่านก่อนหน้า ระบบจะกำหนดฉากเริ่มต้น โดยอัตโนมัติจากสถานะปัจจุบันของอินเทอร์เฟซผู้ใช้
หากคุณไม่ได้ระบุอินสแตนซ์การเปลี่ยนผ่าน ตัวจัดการการเปลี่ยนผ่านจะใช้การเปลี่ยนผ่านอัตโนมัติที่ทําสิ่งที่สมเหตุสมผลสําหรับสถานการณ์ส่วนใหญ่ได้ ดูข้อมูลเพิ่มเติมได้ที่เอกสารอ้างอิง API สำหรับคลาส
TransitionManager
เลือกมุมมองเป้าหมายที่เฉพาะเจาะจง
เฟรมเวิร์กจะใช้การเปลี่ยนฉากกับทุกมุมมองในฉากเริ่มต้นและฉากจบ
โดยค่าเริ่มต้น ในบางกรณี คุณอาจต้องการใช้ภาพเคลื่อนไหวกับมุมมองย่อย
ในฉากเท่านั้น เฟรมเวิร์กช่วยให้คุณเลือกมุมมองที่ต้องการ
เคลื่อนไหวได้ เช่น เฟรมเวิร์กไม่รองรับการเปลี่ยนภาพเคลื่อนไหวของออบเจ็กต์ ListView ดังนั้นอย่าพยายามเปลี่ยนภาพเคลื่อนไหวในระหว่างการเปลี่ยน
แต่ละมุมมองที่การเปลี่ยนภาพเคลื่อนไหวเรียกว่าเป้าหมาย คุณเลือกได้เฉพาะเป้าหมายที่เป็นส่วนหนึ่งของลําดับชั้นของมุมมองที่เชื่อมโยงกับฉาก
หากต้องการนำข้อมูลพร็อพเพอร์ตี้อย่างน้อย 1 รายการออกจากรายการเป้าหมาย ให้เรียกใช้เมธอด
removeTarget()
ก่อนเริ่มการเปลี่ยน หากต้องการเพิ่มเฉพาะมุมมองที่คุณระบุลงใน
รายการเป้าหมาย ให้เรียกใช้ฟังก์ชัน
addTarget()
ดูข้อมูลเพิ่มเติมได้ที่การอ้างอิง API สำหรับคลาส Transition
ระบุทรานซิชันหลายรายการ
หากต้องการให้ภาพเคลื่อนไหวมีประสิทธิภาพสูงสุด ให้จับคู่ภาพเคลื่อนไหวกับประเภทการเปลี่ยนแปลงที่ เกิดขึ้นระหว่างฉาก เช่น หากคุณนำมุมมองบางส่วนออกและเพิ่มมุมมองอื่นๆ ระหว่างฉาก ภาพเคลื่อนไหวแบบจางออกหรือจางเข้าจะช่วยให้เห็นได้อย่างชัดเจนว่ามุมมองบางส่วนไม่พร้อมใช้งานอีกต่อไป หากคุณย้ายมุมมองไปยัง จุดต่างๆ บนหน้าจอ ควรทำให้การเคลื่อนไหวเป็นภาพเคลื่อนไหวเพื่อให้ ผู้ใช้สังเกตเห็นตำแหน่งใหม่ของมุมมอง
คุณไม่จำเป็นต้องเลือกภาพเคลื่อนไหวเพียงรายการเดียว เนื่องจากเฟรมเวิร์กการเปลี่ยนฉาก ช่วยให้คุณรวมเอฟเฟกต์ภาพเคลื่อนไหวไว้ในการเปลี่ยนฉากชุดเดียวที่มีกลุ่ม การเปลี่ยนฉากในตัวหรือการเปลี่ยนฉากที่กำหนดเองแต่ละรายการได้
หากต้องการกำหนดชุดการเปลี่ยนฉากจากคอลเล็กชันการเปลี่ยนฉากใน XML ให้สร้างไฟล์ทรัพยากรในไดเรกทอรี res/transitions/ และแสดงรายการการเปลี่ยนฉากภายใต้องค์ประกอบ TransitionSet ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้แสดงวิธี
ระบุชุดการเปลี่ยนที่มีลักษณะการทำงานเหมือนกับคลาส AutoTransition
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="sequential"> <fade android:fadingMode="fade_out" /> <changeBounds /> <fade android:fadingMode="fade_in" /> </transitionSet>
หากต้องการขยายชุดการเปลี่ยนเป็นออบเจ็กต์
TransitionSet ในโค้ด
ให้เรียกใช้ฟังก์ชัน
TransitionInflater.from()
ในกิจกรรม คลาส TransitionSet ขยายจากคลาส
Transition คุณจึงใช้คลาสนี้กับเครื่องมือจัดการการเปลี่ยนฉากได้เช่นเดียวกับอินสแตนซ์ Transition อื่นๆ
ใช้การเปลี่ยนผ่านโดยไม่มีฉาก
การเปลี่ยนลําดับชั้นของมุมมองไม่ใช่เพียงวิธีเดียวในการแก้ไขอินเทอร์เฟซผู้ใช้ นอกจากนี้ คุณยังทำการเปลี่ยนแปลงได้โดยการเพิ่ม แก้ไข และนำมุมมองของบุตรหลานออกภายใน ลำดับชั้นปัจจุบัน
ตัวอย่างเช่น คุณสามารถใช้การโต้ตอบการค้นหาด้วย
เลย์เอาต์เดียว เริ่มต้นด้วยเลย์เอาต์ที่แสดงช่องป้อนข้อมูลการค้นหาและไอคอนค้นหา
หากต้องการเปลี่ยนอินเทอร์เฟซผู้ใช้เพื่อแสดงผลลัพธ์ ให้นำปุ่มค้นหาออก
เมื่อผู้ใช้แตะปุ่มดังกล่าวโดยเรียกใช้ฟังก์ชัน
ViewGroup.removeView()
และเพิ่มผลการค้นหาโดยเรียกใช้ฟังก์ชัน
ViewGroup.addView()
คุณใช้วิธีนี้ได้หากทางเลือกอื่นคือการมีลำดับชั้น 2 ระดับที่ เกือบจะเหมือนกัน คุณสามารถมีไฟล์เลย์เอาต์ไฟล์เดียว ซึ่งมีลำดับชั้นของ View ที่คุณแก้ไขในโค้ดได้ แทนที่จะสร้างและดูแลรักษาไฟล์เลย์เอาต์ 2 ไฟล์แยกกัน สำหรับความแตกต่างเล็กน้อยในอินเทอร์เฟซผู้ใช้
หากทำการเปลี่ยนแปลงภายในลำดับชั้นการแสดงผลปัจจุบันในลักษณะนี้ คุณไม่จำเป็นต้องสร้างฉาก แต่คุณสามารถสร้างและใช้การเปลี่ยนภาพระหว่าง สถานะ 2 สถานะของลำดับชั้นของมุมมองได้โดยใช้การเปลี่ยนภาพที่ล่าช้า ฟีเจอร์นี้ของ เฟรมเวิร์กการเปลี่ยนฉากจะเริ่มต้นด้วยสถานะลำดับชั้นของมุมมองปัจจุบัน บันทึก การเปลี่ยนแปลงที่คุณทำกับมุมมอง และใช้การเปลี่ยนฉากที่เคลื่อนไหว การเปลี่ยนแปลงเมื่อระบบวาดอินเทอร์เฟซผู้ใช้ใหม่
หากต้องการสร้างการเปลี่ยนฉากที่ล่าช้าภายในลําดับชั้นของมุมมองเดียว ให้ทําตาม ขั้นตอนต่อไปนี้
- เมื่อเกิดเหตุการณ์ที่ทริกเกอร์การเปลี่ยน ให้เรียกใช้ฟังก์ชัน
TransitionManager.beginDelayedTransition()โดยระบุมุมมองหลักของมุมมองทั้งหมด ที่คุณต้องการเปลี่ยนและการเปลี่ยนที่จะใช้ เฟรมเวิร์กจะจัดเก็บสถานะปัจจุบันของมุมมองย่อยและค่าพร็อพเพอร์ตี้ - ทําการเปลี่ยนแปลงมุมมองของเด็กตามที่กรณีการใช้งานของคุณต้องการ เฟรมเวิร์ก จะบันทึกการเปลี่ยนแปลงที่คุณทำกับข้อมูลพร็อพเพอร์ตี้ของมุมมองย่อย
- เมื่อระบบวาดอินเทอร์เฟซผู้ใช้ใหม่ตามการเปลี่ยนแปลงของคุณ เฟรมเวิร์กจะเคลื่อนไหวการเปลี่ยนแปลงระหว่างสถานะเดิมกับสถานะใหม่
ตัวอย่างต่อไปนี้แสดงวิธีสร้างภาพเคลื่อนไหวของการเพิ่ม TextView ลงในลำดับชั้นของ View โดยใช้การเปลี่ยนฉากที่ล่าช้า ข้อมูลโค้ดแรกแสดงไฟล์คำจำกัดความของเลย์เอาต์
res/layout/activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/inputText" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" /> ... </androidx.constraintlayout.widget.ConstraintLayout>
ข้อมูลโค้ดถัดไปแสดงโค้ดที่เคลื่อนไหวการเพิ่มมุมมองข้อความ
กิจกรรมหลัก
Kotlin
setContentView(R.layout.activity_main) val labelText = TextView(this).apply { text = "Label" id = R.id.text } val rootView: ViewGroup = findViewById(R.id.mainLayout) val mFade: Fade = Fade(Fade.IN) TransitionManager.beginDelayedTransition(rootView, mFade) rootView.addView(labelText)
Java
private TextView labelText; private Fade mFade; private ViewGroup rootView; ... // Load the layout. setContentView(R.layout.activity_main); ... // Create a new TextView and set some View properties. labelText = new TextView(this); labelText.setText("Label"); labelText.setId(R.id.text); // Get the root view and create a transition. rootView = (ViewGroup) findViewById(R.id.mainLayout); mFade = new Fade(Fade.IN); // Start recording changes to the view hierarchy. TransitionManager.beginDelayedTransition(rootView, mFade); // Add the new TextView to the view hierarchy. rootView.addView(labelText); // When the system redraws the screen to show this update, // the framework animates the addition as a fade in.
กำหนด Lifecycle Callback การเปลี่ยนผ่าน
วงจรการเปลี่ยนผ่านจะคล้ายกับวงจรกิจกรรม ซึ่งแสดงถึง
สถานะการเปลี่ยนผ่านที่เฟรมเวิร์กตรวจสอบในช่วงเวลาระหว่างการเรียก
ฟังก์ชัน TransitionManager.go() กับการสิ้นสุด
ภาพเคลื่อนไหว ในสถานะวงจรการใช้งานที่สำคัญ เฟรมเวิร์กจะเรียกใช้การเรียกกลับ
ที่กำหนดโดยอินเทอร์เฟซ TransitionListener
เช่น การเรียกกลับของวงจรการเปลี่ยนฉากมีประโยชน์ในการคัดลอกค่าพร็อพเพอร์ตี้ของ View
จากลำดับชั้นของ View เริ่มต้นไปยังลำดับชั้นของ View สุดท้าย
ในระหว่างการเปลี่ยนฉาก คุณไม่สามารถคัดลอกค่าจากมุมมองเริ่มต้นไปยังมุมมองในลำดับชั้นของมุมมองสิ้นสุดได้โดยตรง เนื่องจากลำดับชั้นของมุมมองสิ้นสุดจะไม่ขยายจนกว่าการเปลี่ยนผ่านจะเสร็จสมบูรณ์ แต่คุณต้องจัดเก็บค่า
ในตัวแปร แล้วคัดลอกค่าดังกล่าวลงในลำดับชั้นของมุมมองสุดท้ายเมื่อเฟรมเวิร์ก
เปลี่ยนผ่านเสร็จแล้ว หากต้องการรับการแจ้งเตือนเมื่อการเปลี่ยนผ่านเสร็จสมบูรณ์ ให้ใช้ฟังก์ชัน TransitionListener.onTransitionEnd()
ในกิจกรรม
ดูข้อมูลเพิ่มเติมได้ที่การอ้างอิง API สำหรับคลาส
TransitionListener
ข้อจำกัด
ส่วนนี้จะแสดงข้อจำกัดที่ทราบบางประการของเฟรมเวิร์กการเปลี่ยนฉาก
- ภาพเคลื่อนไหวที่ใช้กับ
SurfaceViewอาจไม่ปรากฏ อย่างถูกต้อง อินสแตนซ์SurfaceViewจะได้รับการอัปเดตจากเธรดที่ไม่ใช่ UI ดังนั้นการอัปเดตอาจไม่ซิงค์กับภาพเคลื่อนไหวของมุมมองอื่นๆ - การเปลี่ยนฉากบางประเภทอาจไม่สร้างเอฟเฟกต์ภาพเคลื่อนไหวที่ต้องการ
เมื่อใช้กับ
TextureView - คลาสที่ขยายเวลา
AdapterViewเช่นListViewจัดการมุมมองย่อยในลักษณะที่ไม่สอดคล้องกับ เฟรมเวิร์กการเปลี่ยนผ่าน หากคุณพยายามเคลื่อนไหวมุมมองโดยอิงตามAdapterViewจอแสดงผลของอุปกรณ์อาจหยุดตอบสนอง - หากพยายามปรับขนาด
TextViewที่มีภาพเคลื่อนไหว ข้อความจะปรากฏในตำแหน่งใหม่ก่อนที่ออบเจ็กต์จะปรับขนาดเสร็จสมบูรณ์ อย่าเคลื่อนไหวการปรับขนาดของมุมมองที่มีข้อความเพื่อหลีกเลี่ยงปัญหานี้