เฟรมเวิร์กการเปลี่ยนรูปแบบของ Android ช่วยให้คุณสร้างภาพเคลื่อนไหวทุกประเภทใน UI ได้โดยระบุเลย์เอาต์เริ่มต้นและเลย์เอาต์สิ้นสุด คุณสามารถเลือกประเภทภาพเคลื่อนไหวที่ต้องการ เช่น การแสดงหรือซ่อนมุมมองแบบค่อยๆ ปรากฏหรือค่อยๆ หายไป หรือเปลี่ยนขนาดมุมมอง และเฟรมเวิร์กการเปลี่ยนจะกำหนดวิธีแสดงภาพเคลื่อนไหวจากเลย์เอาต์เริ่มต้นไปยังเลย์เอาต์สุดท้าย
เฟรมเวิร์กการเปลี่ยนผ่านมีฟีเจอร์ต่อไปนี้
- ภาพเคลื่อนไหวระดับกลุ่ม: ใช้เอฟเฟกต์ภาพเคลื่อนไหวกับมุมมองทั้งหมดในลําดับชั้นของมุมมอง
- ภาพเคลื่อนไหวในตัว: ใช้ภาพเคลื่อนไหวที่กำหนดไว้ล่วงหน้าสำหรับเอฟเฟกต์ทั่วไป เช่น การจางออกหรือการเคลื่อนไหว
- การรองรับไฟล์ทรัพยากร: โหลดลำดับชั้นการแสดงผลและภาพเคลื่อนไหวในตัวจากไฟล์ทรัพยากรของเลย์เอาต์
- Lifecycle Callback: รับ Callback ที่ควบคุมกระบวนการเปลี่ยนแปลงลำดับชั้นและภาพเคลื่อนไหว
ดูโค้ดตัวอย่างที่แสดงภาพเคลื่อนไหวระหว่างการเปลี่ยนแปลงเลย์เอาต์ได้ที่ BasicTransition
ขั้นตอนพื้นฐานในการสร้างภาพเคลื่อนไหวระหว่างเลย์เอาต์ 2 รูปแบบมีดังนี้
- สร้างออบเจ็กต์
Scene
สำหรับเลย์เอาต์เริ่มต้นและสิ้นสุด อย่างไรก็ตาม ฉากของเลย์เอาต์เริ่มต้นมักกำหนดโดยอัตโนมัติจากเลย์เอาต์ปัจจุบัน - สร้างออบเจ็กต์
Transition
เพื่อกำหนดประเภทภาพเคลื่อนไหวที่ต้องการ - เรียกใช้
TransitionManager.go()
จากนั้นระบบจะเรียกใช้ภาพเคลื่อนไหวเพื่อสลับเลย์เอาต์
แผนภาพในรูปที่ 1 แสดงความสัมพันธ์ระหว่างเลย์เอาต์ ฉาก การเปลี่ยนภาพ และภาพเคลื่อนไหวขั้นสุดท้าย
สร้างฉาก
ฉากจะจัดเก็บสถานะของลําดับชั้นมุมมอง ซึ่งรวมถึงมุมมองทั้งหมดและค่าพร็อพเพอร์ตี้ของมุมมอง เฟรมเวิร์กการเปลี่ยนสามารถเรียกใช้ภาพเคลื่อนไหวระหว่าง ฉากเริ่มต้นกับฉากจบได้
คุณสร้างฉากได้จากไฟล์ทรัพยากรเลย์เอาต์หรือจากกลุ่มมุมมองในโค้ด อย่างไรก็ตาม ฉากเริ่มต้นของการเปลี่ยนฉากมักจะกำหนดโดยอัตโนมัติจาก UI ปัจจุบัน
ฉากยังกำหนดการดำเนินการของตนเองที่จะทำงานเมื่อคุณเปลี่ยนฉากได้ด้วย ฟีเจอร์นี้มีประโยชน์ในการล้างการตั้งค่ามุมมองหลังจากที่คุณเปลี่ยนไปใช้ฉากอื่น
สร้างฉากจากทรัพยากรเลย์เอาต์
คุณสามารถสร้างอินสแตนซ์ Scene
จากไฟล์ทรัพยากรเลย์เอาต์ได้โดยตรง ใช้เทคนิคนี้เมื่อลําดับชั้นของมุมมองในไฟล์เป็นแบบคงที่ส่วนใหญ่
ฉากที่ได้แสดงสถานะลําดับชั้นของมุมมอง ณ เวลาที่คุณสร้างอินสแตนซ์ Scene
หากเปลี่ยนลําดับชั้นของมุมมอง ให้สร้างฉากขึ้นมาใหม่ เฟรมเวิร์กจะสร้างฉากจากลําดับชั้นมุมมองทั้งหมดในไฟล์ คุณสร้างฉากจากบางส่วนของไฟล์เลย์เอาต์ไม่ได้
หากต้องการสร้างอินสแตนซ์ Scene
จากไฟล์ทรัพยากรเลย์เอาต์ ให้ดึงข้อมูลรูทของฉากจากเลย์เอาต์เป็น ViewGroup
จากนั้นเรียกใช้ฟังก์ชัน Scene.getSceneForLayout()
ด้วยรูทฉากและรหัสแหล่งข้อมูลของไฟล์เลย์เอาต์ที่มีลําดับชั้นของมุมมองสําหรับฉาก
กำหนดเลย์เอาต์สำหรับฉาก
ข้อมูลโค้ดในส่วนที่เหลือของส่วนนี้จะแสดงวิธีสร้างฉาก 2 ฉากที่มีองค์ประกอบรูทฉากเดียวกัน นอกจากนี้ ตัวอย่างข้อมูลยังแสดงให้เห็นว่าคุณโหลดออบเจ็กต์ Scene
ที่ไม่เกี่ยวข้องหลายรายการได้โดยไม่ต้องบอกเป็นนัยว่าออบเจ็กต์เหล่านั้นเกี่ยวข้องกัน
ตัวอย่างนี้ประกอบด้วยการกำหนดเลย์เอาต์ต่อไปนี้
- เลย์เอาต์หลักของกิจกรรมที่มีป้ายกำกับข้อความและกิจกรรมย่อย
FrameLayout
ConstraintLayout
สำหรับฉากแรกที่มีช่องข้อความ 2 ช่องConstraintLayout
สำหรับฉากที่ 2 ที่มีช่องข้อความ 2 ช่องเดียวกันในลำดับที่แตกต่างกัน
ตัวอย่างนี้ออกแบบมาเพื่อให้ภาพเคลื่อนไหวทั้งหมดเกิดขึ้นภายในเลย์เอาต์ย่อยของเลย์เอาต์หลักสำหรับกิจกรรม ป้ายกํากับข้อความในเลย์เอาต์หลักจะยังคงเป็นแบบคงที่
เลย์เอาต์หลักสําหรับกิจกรรมมีคำจำกัดความดังนี้
<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
ย่อยสําหรับรูทฉาก เลย์เอาต์สำหรับฉากแรกจะรวมอยู่ในไฟล์เลย์เอาต์หลัก
ซึ่งจะช่วยให้แอปแสดงไฟล์ดังกล่าวเป็นส่วนหนึ่งของอินเทอร์เฟซผู้ใช้เริ่มต้นและโหลดไฟล์ดังกล่าวลงในฉากได้ด้วย เนื่องจากเฟรมเวิร์กจะโหลดไฟล์เลย์เอาต์ทั้งไฟล์ลงในฉากได้เท่านั้น
เลย์เอาต์ของฉากแรกจะกำหนดดังนี้
<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" ></androidx.constraintlayout.widget.ConstraintLayout>
เลย์เอาต์ของฉากที่สองมีช่องข้อความ 2 ช่องเดียวกันซึ่งมีรหัสเดียวกัน แต่เรียงลำดับต่างกัน โดยมีคำจำกัดความดังนี้
<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" ></androidx.constraintlayout.widget.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
ที่กำหนดภาพเคลื่อนไหว
เฟรมเวิร์กนี้ให้คุณระบุการเปลี่ยนในตัวในไฟล์ทรัพยากรและเพิ่มพองในโค้ดหรือสร้างอินสแตนซ์การเปลี่ยนในตัวในโค้ดโดยตรง
ชั้น | ติดแท็ก | เอฟเฟ็กต์ |
---|---|---|
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
<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 รายการที่เกือบเหมือนกัน คุณสามารถสร้างไฟล์เลย์เอาต์ 1 ไฟล์ที่มีลําดับชั้นมุมมองที่คุณแก้ไขในโค้ดแทนการสร้างและดูแลรักษาไฟล์เลย์เอาต์ 2 ไฟล์แยกกันเพื่อความแตกต่างเล็กน้อยในอินเทอร์เฟซผู้ใช้
หากทําการเปลี่ยนแปลงภายในลําดับชั้นของมุมมองปัจจุบันในลักษณะนี้ คุณไม่จําเป็นต้องสร้างฉาก แต่คุณสามารถสร้างและใช้การเปลี่ยนระหว่างลำดับชั้นการแสดงผล 2 สถานะโดยใช้การเปลี่ยนแบบล่าช้า ฟีเจอร์นี้ของเฟรมเวิร์กทรานซิชันจะเริ่มต้นจากสถานะลําดับชั้นมุมมองปัจจุบัน บันทึกการเปลี่ยนแปลงที่คุณทํากับมุมมอง และนําทรานซิชันที่แสดงภาพการเปลี่ยนแปลงเมื่อระบบวาดอินเทอร์เฟซผู้ใช้อีกครั้ง
หากต้องการสร้างการเปลี่ยนที่ล่าช้าภายในลําดับชั้นมุมมองเดียว ให้ทําตามขั้นตอนต่อไปนี้
- เมื่อเกิดเหตุการณ์ที่ทริกเกอร์การเปลี่ยน ให้เรียกใช้ฟังก์ชัน
TransitionManager.beginDelayedTransition()
โดยระบุมุมมองระดับบนสุดของมุมมองทั้งหมดที่คุณต้องการเปลี่ยนแปลงและเปลี่ยนไปใช้ เฟรมเวิร์กจะจัดเก็บสถานะปัจจุบันของมุมมองย่อยและค่าพร็อพเพอร์ตี้ของมุมมองย่อย - ทำการเปลี่ยนแปลงข้อมูลพร็อพเพอร์ตี้ย่อยตาม Use Case ของคุณ เฟรมเวิร์กจะบันทึกการเปลี่ยนแปลงที่คุณทำกับมุมมองและพร็อพเพอร์ตี้ของบุตรหลาน
- เมื่อระบบวาดอินเทอร์เฟซผู้ใช้ใหม่ตามการเปลี่ยนแปลงของคุณ เฟรมเวิร์กจะแสดงภาพเคลื่อนไหวของการเปลี่ยนแปลงระหว่างสถานะเดิมกับสถานะใหม่
ตัวอย่างต่อไปนี้แสดงวิธีทำให้การเพิ่มมุมมองข้อความในลําดับชั้นของมุมมองเคลื่อนไหวโดยใช้การเปลี่ยนแบบเลื่อนเวลา ข้อมูลโค้ดแรกแสดงไฟล์การกำหนดเลย์เอาต์
<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
การเรียกกลับวงจรการเปลี่ยนเฟสมีประโยชน์ เช่น สำหรับการคัดลอกค่าพร็อพเพอร์ตี้ของมุมมองจากลําดับชั้นมุมมองเริ่มต้นไปยังลําดับชั้นมุมมองสุดท้ายระหว่างการเปลี่ยนฉาก คุณไม่สามารถคัดลอกค่าจากมุมมองเริ่มต้นไปยังมุมมองในลําดับชั้นของมุมมองสิ้นสุดได้ เนื่องจากระบบจะไม่ขยายลําดับชั้นของมุมมองสิ้นสุดจนกว่าการเปลี่ยนผ่านจะเสร็จสมบูรณ์ แต่คุณต้องเก็บค่าไว้ในตัวแปร แล้วคัดลอกค่านั้นลงในลําดับชั้นมุมมองที่สิ้นสุดเมื่อเฟรมเวิร์กทําการเปลี่ยนเสร็จแล้ว หากต้องการรับการแจ้งเตือนเมื่อการเปลี่ยนเสร็จสมบูรณ์ ให้ใช้ฟังก์ชัน TransitionListener.onTransitionEnd()
ในกิจกรรม
ดูข้อมูลเพิ่มเติมได้ที่การอ้างอิง API สำหรับคลาส TransitionListener
ข้อจำกัด
ส่วนนี้จะแสดงข้อจำกัดที่ทราบบางส่วนของเฟรมเวิร์กการเปลี่ยนผ่าน
- ภาพเคลื่อนไหวที่ใช้กับ
SurfaceView
อาจไม่ปรากฏอย่างถูกต้อง อินสแตนซ์SurfaceView
มีการอัปเดตจากเทรดที่ไม่ใช่ UI การอัปเดตจึงอาจไม่ซิงค์กับภาพเคลื่อนไหวของการแสดงผลอื่นๆ - การเปลี่ยนบางประเภทอาจไม่สร้างเอฟเฟกต์ภาพเคลื่อนไหวตามที่ต้องการเมื่อใช้กับ
TextureView
- ชั้นเรียนที่ขยาย
AdapterView
เช่นListView
จะจัดการมุมมองของบุตรหลานในลักษณะที่ใช้ไม่ได้กับเฟรมเวิร์กการเปลี่ยน หากคุณพยายามทำให้มุมมองเคลื่อนไหวตามAdapterView
จอแสดงผลของอุปกรณ์อาจหยุดตอบสนอง - หากคุณพยายามปรับขนาด
TextView
ด้วยภาพเคลื่อนไหว ข้อความจะปรากฏขึ้นที่ตำแหน่งใหม่ก่อนที่ระบบจะปรับขนาดออบเจ็กต์ให้เสร็จสมบูรณ์ หลีกเลี่ยงปัญหานี้โดยอย่าใช้ภาพเคลื่อนไหวในการปรับขนาดของมุมมองที่มีข้อความ