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