สร้างภาพเคลื่อนไหวการเปลี่ยนแปลงการออกแบบโดยใช้การเปลี่ยน

ลองใช้วิธีการเขียน
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีใช้ภาพเคลื่อนไหวใน Compose

เฟรมเวิร์กการเปลี่ยนของ Android ช่วยให้คุณทำภาพเคลื่อนไหวได้ทุกประเภท UI โดยแสดงการออกแบบเริ่มต้นและสิ้นสุด คุณเลือกประเภทภาพเคลื่อนไหวที่ต้องการ เช่น เพื่อทำให้มุมมองจางลงได้ เข้าหรือออก หรือเปลี่ยนขนาดมุมมอง และเฟรมเวิร์กการเปลี่ยนจะกำหนด วิธีสร้างภาพเคลื่อนไหวจากเลย์เอาต์เริ่มต้นไปยังเลย์เอาต์สุดท้าย

เฟรมเวิร์กการเปลี่ยนจะมีฟีเจอร์ต่อไปนี้

  • ภาพเคลื่อนไหวระดับกลุ่ม ใช้เอฟเฟ็กต์ภาพเคลื่อนไหวกับทุกมุมมองในลำดับชั้นการดู
  • ภาพเคลื่อนไหวในตัว: สามารถใช้ภาพเคลื่อนไหวที่กำหนดไว้ล่วงหน้าสำหรับเอฟเฟ็กต์ทั่วไป เช่น การค่อยๆ จางลงหรือการเคลื่อนไหว
  • การรองรับไฟล์แหล่งข้อมูล โหลดลำดับชั้นการแสดงผลและภาพเคลื่อนไหวในตัวจากไฟล์ทรัพยากรของเลย์เอาต์
  • Callback ของวงจร: รับ Callback ที่ให้การควบคุมภาพเคลื่อนไหวและลําดับชั้น กระบวนการเปลี่ยนแปลง

ดูโค้ดตัวอย่างที่เคลื่อนไหวระหว่างการเปลี่ยนแปลงเลย์เอาต์ได้ที่ การเปลี่ยนแบบพื้นฐาน

ขั้นตอนพื้นฐานในการสร้างภาพเคลื่อนไหวระหว่างเลย์เอาต์ 2 เลย์เอาต์มีดังนี้

  1. สร้างออบเจ็กต์ Scene สำหรับ เลย์เอาต์เริ่มต้นและสิ้นสุด แต่ฉากของเลย์เอาต์เริ่มต้น มักถูกกำหนดโดยอัตโนมัติจากการจัดวางในปัจจุบัน
  2. สร้าง Transition เพื่อกำหนดประเภทของภาพเคลื่อนไหวที่คุณต้องการ
  3. โทร TransitionManager.go() ระบบจะเรียกใช้ภาพเคลื่อนไหวเพื่อสลับเลย์เอาต์

แผนภาพในรูปที่ 1 แสดงความสัมพันธ์ระหว่างเลย์เอาต์ ทั้งฉาก การเปลี่ยนฉาก และภาพเคลื่อนไหวขั้นสุดท้าย

รูปที่ 1 ภาพพื้นฐานของ วิธีที่เฟรมเวิร์กการเปลี่ยนสร้างภาพเคลื่อนไหว

สร้างฉาก

ฉากจะจัดเก็บสถานะของลำดับชั้นการดู ซึ่งรวมถึงมุมมองทั้งหมดและ ของพร็อพเพอร์ตี้ เฟรมเวิร์กการเปลี่ยนสามารถเรียกใช้ภาพเคลื่อนไหวระหว่างการเริ่มต้น และฉากจบ

คุณสามารถสร้างฉากจากเลย์เอาต์ได้ ไฟล์ทรัพยากรหรือจากกลุ่มมุมมองในโค้ดของคุณ อย่างไรก็ตาม ฉากเริ่มต้นของการเปลี่ยนผ่านมักถูกกำหนดโดยอัตโนมัติจาก UI ปัจจุบัน

นอกจากนี้ยังกำหนดการกระทำของฉากที่จะทำงานเมื่อคุณเปลี่ยนฉากได้ด้วย ฟีเจอร์นี้มีประโยชน์ในการล้างการตั้งค่ามุมมองหลังจากที่คุณ เปลี่ยนเป็นฉาก

สร้างฉากจากทรัพยากรเลย์เอาต์

คุณสร้างอินสแตนซ์ Scene ได้โดยตรงจากทรัพยากรเลย์เอาต์ ใช้เทคนิคนี้เมื่อลำดับชั้นการดูในไฟล์ส่วนใหญ่คงที่ ฉากที่เป็นผลลัพธ์จะแสดงสถานะของลำดับชั้นการดู ณ เวลาที่คุณ สร้างอินสแตนซ์ Scene แล้ว หากคุณเปลี่ยนลำดับชั้นการแสดงผล เพื่อสร้างฉากใหม่ เฟรมเวิร์กสร้างฉากจากมุมมองทั้งหมด ลำดับชั้นในไฟล์ คุณไม่สามารถสร้างฉากจากบางส่วนของไฟล์เลย์เอาต์ได้

หากต้องการสร้างอินสแตนซ์ Scene จากไฟล์ทรัพยากรเลย์เอาต์ ให้เรียกข้อมูล รากของฉากจากเค้าโครงของคุณ ViewGroup จากนั้นเรียกเมธอด Scene.getSceneForLayout() ที่มีรากของฉากและรหัสทรัพยากรของไฟล์การออกแบบที่ ที่มีลำดับชั้นของมุมมองสำหรับฉากนั้นๆ

กำหนดเลย์เอาต์สำหรับฉาก

ข้อมูลโค้ดในส่วนที่เหลือของส่วนนี้แสดงวิธีการสร้าง ฉากต่างๆ ที่มีองค์ประกอบรากของฉากเดียวกัน นอกจากนี้ ข้อมูลโค้ดยังแสดงให้เห็นถึง ที่คุณสามารถโหลดออบเจ็กต์ 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_โหมด.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" >
    
    
</androidx.constraintlayout.widget.ConstraintLayout>

เลย์เอาต์สำหรับฉากที่ 2 มีช่องข้อความ 2 ช่องเหมือนกัน โดยมีช่อง รหัสเดียวกัน โดยเรียงลำดับต่างกัน โดยมีคำจำกัดความดังนี้

res/layout/another_views.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" >
    
    
</androidx.constraintlayout.widget.ConstraintLayout>

สร้างฉากจากเลย์เอาต์

หลังจากที่คุณสร้างคำจำกัดความสำหรับเค้าโครงข้อจำกัดทั้ง 2 เค้าโครงแล้ว คุณสามารถดู สำหรับแต่ละรายการ ซึ่งจะช่วยให้คุณสลับไปมาระหว่าง UI ทั้งสอง การกำหนดค่าเอง คุณต้องมีการอ้างอิงถึงรากของฉากและเลย์เอาต์เพื่อให้ได้ฉาก รหัสทรัพยากร

ข้อมูลโค้ดต่อไปนี้แสดงวิธีรับการอ้างอิงไปยังรากของฉากและ สร้างออบเจ็กต์ 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()

วงจรการเปลี่ยนจะคล้ายกับวงจรกิจกรรม และแสดงถึง การเปลี่ยนแปลงจะระบุว่าเฟรมเวิร์กการตรวจสอบระหว่างการเริ่มต้นกับ จากภาพเคลื่อนไหว ที่ประสบความสำเร็จ ในสถานะของวงจรการใช้งานที่สำคัญ เฟรมเวิร์กนี้จะเรียกใช้ ฟังก์ชัน Callback ที่คุณสามารถนำไปใช้เพื่อปรับอินเทอร์เฟซผู้ใช้ได้ที่ ในระยะต่างๆ ของการเปลี่ยนแปลง

สร้างการเปลี่ยน

ส่วนก่อนหน้านี้แสดงวิธีการสร้างฉากที่แสดงถึงสภาวะของ ลำดับชั้นการแสดงผลที่ต่างกัน เมื่อคุณกำหนดฉากเริ่มต้นและสิ้นสุดแล้ว เพื่อเปลี่ยนได้ ให้สร้างออบเจ็กต์ 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 ดังนั้นอย่าพยายามทำให้วัตถุเคลื่อนไหวในระหว่างการเปลี่ยน

แต่ละมุมมองที่มีการเคลื่อนไหวการเปลี่ยนแปลงจะเรียกว่าเป้าหมาย คุณจะทำได้เพียง เลือกเป้าหมายที่เป็นส่วนหนึ่งของลำดับชั้นการแสดงผลที่เชื่อมโยงกับฉาก

หากต้องการลบข้อมูลพร็อพเพอร์ตี้อย่างน้อยหนึ่งรายการออกจากรายการเป้าหมาย ให้เรียกเมธอด 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. เมื่อเหตุการณ์ที่ทำให้เกิดการเปลี่ยนเกิดขึ้น ให้เรียกเมธอด TransitionManager.beginDelayedTransition() ทำให้ดูมุมมองระดับบนสุดของการดูทั้งหมด ที่คุณต้องการเปลี่ยนแปลงและเปลี่ยนไปใช้ เฟรมเวิร์กนี้จะจัดเก็บ สถานะของมุมมองย่อยและค่าพร็อพเพอร์ตี้
  2. เปลี่ยนแปลงมุมมองย่อยตามที่กรณีการใช้งานของคุณกำหนดไว้ เฟรมเวิร์ก บันทึกการเปลี่ยนแปลงที่คุณทำกับข้อมูลพร็อพเพอร์ตี้ย่อยและพร็อพเพอร์ตี้ย่อย
  3. ระบบจะเริ่มอินเทอร์เฟซผู้ใช้อีกครั้งตามการเปลี่ยนแปลงของคุณ ภาพเคลื่อนไหวของการเปลี่ยนแปลงระหว่างรัฐเดิมกับสถานะใหม่

ตัวอย่างต่อไปนี้จะแสดงวิธีทำให้การเพิ่มมุมมองข้อความเป็นภาพเคลื่อนไหวลงในมุมมอง ลำดับชั้นที่ใช้การเปลี่ยนแบบล่าช้า ตัวอย่างข้อมูลแรกแสดงเลย์เอาต์ ไฟล์คำจำกัดความ:

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.

กำหนด Callback ของวงจรการเปลี่ยน

วงจรการเปลี่ยนจะคล้ายกับวงจรกิจกรรม ซึ่งแสดงถึง การเปลี่ยนแปลงนี้ระบุว่าเฟรมเวิร์กจะตรวจสอบในช่วงระยะเวลาระหว่างการโทร ไปยังฟังก์ชัน TransitionManager.go() และความสมบูรณ์ ภาพเคลื่อนไหว เมื่ออยู่ในสภาวะของวงจรที่สำคัญ เฟรมเวิร์กนี้จะเรียกใช้ Callback กำหนดโดยTransitionListener ของ Google

Callback ของวงจรการเปลี่ยนมีประโยชน์ ตัวอย่างเช่น สำหรับการคัดลอกข้อมูลพร็อพเพอร์ตี้ ค่าพร็อพเพอร์ตี้จากลำดับชั้นการแสดงผลเริ่มต้นไปจนถึงลำดับชั้นการแสดงผลสิ้นสุด ระหว่างการเปลี่ยนฉาก คุณไม่สามารถคัดลอกค่าจากมุมมองเริ่มต้นไปยัง มุมมองในลำดับชั้นการแสดงผลสิ้นสุด เนื่องจากลำดับชั้นของมุมมองสิ้นสุดไม่ใช่ พองขึ้นจนกว่าการเปลี่ยนจะเสร็จสมบูรณ์ แต่คุณจะต้องเก็บค่า ลงในตัวแปร แล้วคัดลอกไปยังลำดับชั้นของมุมมองสิ้นสุดเมื่อเฟรมเวิร์ก เสร็จสิ้นการเปลี่ยนแปลงแล้ว หากต้องการรับการแจ้งเตือนเมื่อการเปลี่ยนเสร็จสมบูรณ์ ติดตั้งใช้งาน TransitionListener.onTransitionEnd() ในกิจกรรมของคุณ

สำหรับข้อมูลเพิ่มเติม โปรดดูข้อมูลอ้างอิง API สำหรับ TransitionListener

ข้อจำกัด

ส่วนนี้แสดงข้อจำกัดที่ทราบบางประการของเฟรมเวิร์กการเปลี่ยน

  • ใช้ภาพเคลื่อนไหวกับ SurfaceView อาจไม่ปรากฏ อย่างถูกต้อง อินสแตนซ์ SurfaceView รายการได้รับการอัปเดตจากเทรดที่ไม่ใช่ UI ดังนั้น การอัปเดตอาจไม่ซิงค์กับภาพเคลื่อนไหวของมุมมองอื่นๆ
  • การเปลี่ยนบางประเภทอาจไม่สร้างเอฟเฟกต์ภาพเคลื่อนไหวตามที่ต้องการ เมื่อใช้กับ TextureView
  • คลาสที่ขยายได้ AdapterView เช่น ListView จัดการมุมมองของบุตรหลานในลักษณะที่ไม่สอดคล้องกับ เฟรมเวิร์กการเปลี่ยน หากคุณพยายามทำให้มุมมองเคลื่อนไหวโดยอิงจาก AdapterView จอแสดงผลของอุปกรณ์อาจหยุดตอบสนอง
  • หากคุณพยายามปรับขนาดTextViewด้วย ภาพเคลื่อนไหว ข้อความจะปรากฏที่ตำแหน่งใหม่ก่อนที่วัตถุจะสมบูรณ์ ปรับขนาดแล้ว เพื่อหลีกเลี่ยงปัญหานี้ โปรดอย่าทำให้การปรับขนาดของมุมมองที่มี ข้อความ