ระหว่างรันไทม์
FragmentManager
เพิ่ม นำออก แทนที่ หรือดำเนินการอื่นๆ ด้วย Fragment ได้
เพื่อตอบสนองต่อการโต้ตอบของผู้ใช้ ส่วนย่อยแต่ละชุดมีการเปลี่ยนแปลงที่คุณ
คอมมิต เรียกว่า ธุรกรรม ซึ่งคุณสามารถระบุสิ่งที่ต้องทำได้ใน
ธุรกรรมโดยใช้ API จาก
FragmentTransaction
คุณสามารถจัดกลุ่มการดำเนินการหลายอย่างให้เป็นธุรกรรมเดียว เช่น
ธุรกรรมนั้นสามารถเพิ่มหรือแทนที่ส่วนย่อยได้หลายรายการ การจัดกลุ่มนี้อาจ
มีประโยชน์สำหรับกรณีที่คุณมี
ส่วนย่อยหลายๆ ข้างบน
หน้าจอเดียวกัน เช่น แยกมุมมอง
คุณสามารถบันทึกธุรกรรมแต่ละรายการลงในสแต็กแบ็กสแต็กที่จัดการโดย
FragmentManager
ซึ่งช่วยให้ผู้ใช้สามารถย้อนกลับผ่าน
การเปลี่ยนแปลงส่วนย่อย - คล้ายกับการย้อนกลับไปยังกิจกรรมต่างๆ
คุณสามารถรับอินสแตนซ์ของ FragmentTransaction
ได้จาก FragmentManager
ด้วยการเรียก beginTransaction()
ดังที่ปรากฏในตัวอย่างต่อไปนี้:
Kotlin
val fragmentManager = ... val fragmentTransaction = fragmentManager.beginTransaction()
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
การโทรครั้งสุดท้ายในแต่ละ FragmentTransaction
ต้องทำธุรกรรม
สัญญาณการโทร commit()
ไปยัง FragmentManager
ว่าการดำเนินการทั้งหมด
เพิ่มลงในธุรกรรมแล้ว
Kotlin
val fragmentManager = ... // The fragment-ktx module provides a commit block that automatically // calls beginTransaction and commit for you. fragmentManager.commit { // Add operations here }
Java
FragmentManager fragmentManager = ... FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); // Add operations here fragmentTransaction.commit();
อนุญาตให้เรียงลำดับการเปลี่ยนแปลงสถานะส่วนย่อยใหม่
FragmentTransaction
แต่ละรายการควรใช้ setReorderingAllowed(true)
:
Kotlin
supportFragmentManager.commit { ... setReorderingAllowed(true) }
Java
FragmentManager fragmentManager = ... fragmentManager.beginTransaction() ... .setReorderingAllowed(true) .commit();
สำหรับความเข้ากันได้ของลักษณะการทำงาน แฟล็กการจัดเรียงใหม่ไม่ได้เปิดใช้โดยค่าเริ่มต้น
อย่างไรก็ตาม จําเป็นเพื่อให้ FragmentManager
ทํางานได้อย่างถูกต้อง
FragmentTransaction
ของคุณ โดยเฉพาะเมื่อทำงานกับสแต็กด้านหลัง
และแสดงภาพเคลื่อนไหวและการเปลี่ยนภาพ การเปิดใช้งานการทำเครื่องหมายจะทำให้มั่นใจว่า
ธุรกรรมหลายรายการจะถูกดำเนินการร่วมกัน ส่วนย่อยที่เป็นสื่อกลาง
(เช่น รายการที่เพิ่มแล้วแทนที่ทันที) ดำเนินการไม่สำเร็จ
มีการเปลี่ยนแปลงวงจรหรือมีการดำเนินการภาพเคลื่อนไหวหรือการเปลี่ยนภาพ โปรดทราบว่า
แฟล็กนี้จะส่งผลต่อทั้งการดำเนินการครั้งแรกของธุรกรรมและการย้อนกลับ
การทำธุรกรรมกับ popBackStack()
การเพิ่มและนำส่วนย่อยออก
หากต้องการเพิ่มส่วนย่อยใน FragmentManager
ให้โทร
add()
เกี่ยวกับธุรกรรม เมธอดนี้ได้รับ
รหัสของคอนเทนเนอร์สำหรับส่วนย่อย รวมถึงชื่อคลาสของ
ส่วนย่อยที่ต้องการเพิ่ม ส่วนย่อยที่เพิ่มถูกย้ายไปยัง RESUMED
ขอแนะนำให้คอนเทนเนอร์เป็น
FragmentContainerView
ที่เป็นส่วนหนึ่งของลำดับชั้นการแสดงผล
หากต้องการนำส่วนย่อยออกจากโฮสต์ ให้เรียก
remove()
การส่งผ่านในอินสแตนซ์ส่วนย่อยที่ดึงมาจากส่วนย่อย
ผ่าน findFragmentById()
หรือ findFragmentByTag()
หากมีการเพิ่มมุมมองของส่วนย่อยลงในคอนเทนเนอร์ก่อนหน้านี้ มุมมองจะเป็น
นำออกจากคอนเทนเนอร์ ณ จุดนี้ ย้ายส่วนย่อยที่นำออกแล้ว
เป็นสถานะ DESTROYED
ใช้
replace()
เพื่อแทนที่ส่วนย่อยที่มีอยู่ในคอนเทนเนอร์ด้วยอินสแตนซ์ของ
คลาสส่วนย่อยใหม่ที่คุณให้ไว้ การโทรไปยัง replace()
เทียบเท่ากับ
การเรียก remove()
ด้วยส่วนย่อยในคอนเทนเนอร์และเพิ่ม
ลงในคอนเทนเนอร์เดียวกันนั้น
ข้อมูลโค้ดต่อไปนี้แสดงวิธีแทนที่ส่วนย่อยหนึ่งด้วยอีกส่วนหนึ่ง
Kotlin
// Create new fragment val fragmentManager = // ... // Create and commit a new transaction fragmentManager.commit { setReorderingAllowed(true) // Replace whatever is in the fragment_container view with this fragment replace<ExampleFragment>(R.id.fragment_container) }
Java
// Create new fragment and transaction FragmentManager fragmentManager = ... FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.setReorderingAllowed(true); // Replace whatever is in the fragment_container view with this fragment transaction.replace(R.id.fragment_container, ExampleFragment.class, null); // Commit the transaction transaction.commit();
ในตัวอย่างนี้ อินสแตนซ์ใหม่ของ ExampleFragment
จะแทนที่ส่วนย่อย
หากมี ซึ่งขณะนี้อยู่ในคอนเทนเนอร์เลย์เอาต์ที่ระบุโดย
R.id.fragment_container
โดยค่าเริ่มต้น การเปลี่ยนแปลงที่ทำใน FragmentTransaction
จะไม่เพิ่มลงใน
กองหลัง หากต้องการบันทึกการเปลี่ยนแปลงดังกล่าว คุณสามารถเรียกใช้
addToBackStack()
ใน FragmentTransaction
สำหรับข้อมูลเพิ่มเติม โปรดดู
ตัวจัดการส่วนย่อย
คอมมิตไม่พร้อมกัน
การโทร
commit()
ไม่ได้ทำธุรกรรมโดยทันที แต่ธุรกรรมจะเป็น
ให้ทำงานในเธรด UI หลักทันทีที่สามารถทำได้ ถ้า
แต่คุณสามารถโทรหา
commitNow()
เพื่อเรียกใช้ธุรกรรมส่วนย่อยบนเธรด UI ของคุณทันที
โปรดทราบว่า commitNow
ไม่สามารถใช้งานร่วมกับ addToBackStack
หรือ
คุณสามารถเรียกใช้ FragmentTransactions
ที่รอดำเนินการทั้งหมดที่ส่งโดย
commit()
ที่ยังไม่ได้เรียกใช้โดยโทรไปที่ executePendingTransactions()
วิธีนี้เข้ากันได้กับ addToBackStack
สำหรับ Use Case ส่วนใหญ่ คุณแค่ต้องมี commit()
เท่านั้น
ลำดับการดำเนินการมีความสำคัญ
ลำดับที่คุณดำเนินการภายใน
FragmentTransaction
เป็นสิ่งสำคัญ โดยเฉพาะอย่างยิ่งเมื่อใช้ setCustomAnimations()
ช่วงเวลานี้
จะนำภาพเคลื่อนไหวที่ระบุไปใช้กับการดำเนินการส่วนย่อยทั้งหมดที่
ทำตามคำนั้น
Kotlin
supportFragmentManager.commit { setCustomAnimations(enter1, exit1, popEnter1, popExit1) add<ExampleFragment>(R.id.container) // gets the first animations setCustomAnimations(enter2, exit2, popEnter2, popExit2) add<ExampleFragment>(R.id.container) // gets the second animations }
Java
getSupportFragmentManager().beginTransaction() .setCustomAnimations(enter1, exit1, popEnter1, popExit1) .add(R.id.container, ExampleFragment.class, null) // gets the first animations .setCustomAnimations(enter2, exit2, popEnter2, popExit2) .add(R.id.container, ExampleFragment.class, null) // gets the second animations .commit()
จำกัดวงจรของส่วนย่อย
FragmentTransactions
อาจส่งผลต่อสถานะวงจรของผู้ใช้ได้
ส่วนย่อยที่เพิ่มเข้ามาภายในขอบเขตของธุรกรรม เมื่อสร้าง
FragmentTransaction
,
setMaxLifecycle()
กำหนดสถานะสูงสุดสำหรับส่วนย่อยที่ระบุ ตัวอย่างเช่น
ViewPager2
ใช้
setMaxLifecycle()
เพื่อจำกัดส่วนย่อยบนหน้าจอให้เป็นสถานะ STARTED
การแสดงและซ่อนมุมมองของส่วนย่อย
ใช้เมธอด FragmentTransaction
show()
และ
hide()
เพื่อแสดงหรือซ่อนมุมมองของส่วนย่อยที่เพิ่มลงในคอนเทนเนอร์
วิธีการเหล่านี้จะกำหนดการแสดงมุมมองของส่วนย่อยโดยไม่มีผลกระทบ
วงจรของส่วนย่อย
แม้ว่าคุณจะไม่จำเป็นต้องใช้ธุรกรรม Fragment เพื่อเปิด/ปิดการมองเห็น ของมุมมองภายในส่วนย่อย วิธีการเหล่านี้จะมีประโยชน์สำหรับกรณีที่ คุณต้องการเชื่อมโยงกับการเปลี่ยนแปลงสถานะการเปิดเผย ธุรกรรมในแบ็กสแต็ก
การติดและแยกส่วน
เมธอด FragmentTransaction
detach()
ปลดส่วนต่างๆ ออกจาก UI เพื่อทำลายลำดับชั้นการแสดงผล ส่วนย่อย
จะยังคงอยู่ในสถานะเดิม (STOPPED
) เช่นเดียวกับเมื่อนำไปวางในสแต็กด้านหลัง
ซึ่งหมายความว่าส่วนย่อยถูกนำออกจาก UI แต่ยังคงได้รับการจัดการโดย
การจัดการส่วนย่อย
attach()
ระบบจะแนบส่วนย่อยที่ถูกปลดออกก่อนหน้านี้อีกครั้ง
ซึ่งจะทำให้เกิดการสร้างลำดับชั้นการแสดงผลขึ้นมาใหม่ โดยแนบอยู่กับ UI
และแสดงไว้
เมื่อ FragmentTransaction
จัดว่าเป็นชุดการดำเนินการแบบอะตอมเดี่ยว
การเรียกไปยังทั้ง detach
และ attach
บนอินสแตนซ์ Fragment เดียวกันใน
ธุรกรรมเดียวกันยกเลิกกันได้อย่างมีประสิทธิภาพ ดังนั้นจึงหลีกเลี่ยง
การทำลายและการสร้าง UI ของส่วนย่อยในทันที ใช้
ธุรกรรม คั่นด้วย executePendingOperations()
หากใช้ commit()
ถ้าต้องการถอดและแนบแฟรกเมนต์ใหม่ทันที