ตัวจัดการส่วนย่อย

FragmentManager คือ คลาสที่รับผิดชอบการดำเนินการในส่วนย่อยของแอป เช่น เป็นการเพิ่ม ลบ หรือแทนที่รูปภาพเหล่านั้น แล้วเพิ่มลงในสแต็กด้านหลัง

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

หน้านี้ครอบคลุมเนื้อหาต่อไปนี้

  • วิธีเข้าถึง FragmentManager
  • บทบาทของ FragmentManager ที่เกี่ยวข้องกับกิจกรรมและส่วนย่อยของคุณ
  • วิธีจัดการแบ็กเอนด์ด้วย FragmentManager
  • วิธีระบุข้อมูลและการอ้างอิงให้กับส่วนย่อย

เข้าถึง FragmentManager

คุณเข้าถึง FragmentManager ได้จากกิจกรรมหรือจากส่วนย่อย

FragmentActivity และคลาสย่อย เช่น AppCompatActivity, มีสิทธิ์เข้าถึง FragmentManager ผ่านทาง getSupportFragmentManager()

Fragment สามารถโฮสต์ Fragment ย่อยได้ตั้งแต่ 1 รายการขึ้นไป ภายใน ส่วนย่อย คุณสามารถรับการอ้างอิงไปยัง FragmentManager ที่จัดการ ส่วนย่อยของส่วนย่อย getChildFragmentManager() หากต้องการเข้าถึงโฮสต์ FragmentManager คุณสามารถใช้ getParentFragmentManager()

นี่เป็น 2 ตัวอย่างสำหรับดูความสัมพันธ์ระหว่าง ส่วนย่อย โฮสต์ และอินสแตนซ์ FragmentManager ที่เชื่อมโยง แยกกัน

วันที่ ตัวอย่างเค้าโครง UI สองตัวอย่างที่แสดงความสัมพันธ์ระหว่าง
            ส่วนย่อยและกิจกรรมโฮสต์
รูปที่ 1 ตัวอย่างเลย์เอาต์ UI 2 รายการที่แสดง ความสัมพันธ์ระหว่างส่วนย่อยและกิจกรรมโฮสต์

รูปที่ 1 แสดงตัวอย่าง 2 รายการ แต่ละรายการมีโฮสต์กิจกรรมเดียว กิจกรรมโฮสต์ในทั้ง 2 ตัวอย่างนี้แสดงการนำทางระดับบนสุดไปยัง ผู้ใช้ในฐานะ BottomNavigationView ซึ่งมีหน้าที่เปลี่ยนส่วนย่อยของโฮสต์กับ บนหน้าจอในแอป แต่ละหน้าจอจะเป็นคนละหน้าจอกัน

ส่วนย่อยของโฮสต์ในตัวอย่างที่ 1 โฮสต์ส่วนย่อยย่อย 2 รายการที่ ที่กลายเป็นหน้าจอแยกมุมมอง ส่วนย่อยของโฮสต์ในตัวอย่างที่ 2 โฮสต์ ส่วนย่อยเดี่ยวที่รวมกันเป็นส่วนย่อยของการแสดงผล ปัดมุมมอง

ด้วยการตั้งค่านี้ คุณสามารถคิดเกี่ยวกับแต่ละโฮสต์ว่ามี FragmentManager ที่เกี่ยวข้องซึ่งจะจัดการ Fragment ย่อย มีภาพประกอบอยู่ใน รูปที่ 2 พร้อมด้วยการแมปอสังหาริมทรัพย์ระหว่าง supportFragmentManager parentFragmentManager และ childFragmentManager

วันที่ โฮสต์แต่ละรายการจะมี FragmentManager ของตัวเองเชื่อมโยงอยู่
            ที่จัดการส่วนย่อยย่อยของตัวเอง
รูปที่ 2 แต่ละโฮสต์มี FragmentManager ที่เชื่อมโยงกับองค์กรซึ่งจัดการ ส่วนย่อย

พร็อพเพอร์ตี้ FragmentManager ที่เหมาะสมที่จะอ้างอิงขึ้นอยู่กับว่า Callsite อยู่ในลำดับชั้นของ Fragment พร้อมด้วยเครื่องมือจัดการ Fragment ที่คุณพยายามเข้าถึง

เมื่อมีการอ้างอิง FragmentManager แล้ว คุณสามารถใช้เพื่อ จัดการส่วนย่อยที่แสดงต่อผู้ใช้

ส่วนย่อย

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

หากคุณต้องการแสดงส่วนย่อยหลายรายการพร้อมกัน เช่น ในมุมมองแยกหน้าจอ หรือแดชบอร์ด คุณสามารถใช้ส่วนย่อยย่อยที่จัดการโดย ปลายทางและเครื่องมือจัดการ Fragment ย่อย

กรณีการใช้งานอื่นๆ สำหรับส่วนย่อยย่อยมีดังต่อไปนี้

  • แสดงสไลด์บนหน้าจอ, ใช้ ViewPager2 ในส่วนระดับบนสุดเพื่อจัดการชุดข้อมูลย่อย ส่วนย่อย
  • การนำทางย่อยภายในชุดของหน้าจอที่เกี่ยวข้อง
  • Jetpack การนำทางใช้ส่วนย่อยย่อยเป็นปลายทางแต่ละรายการ CANNOT TRANSLATE กิจกรรมมี NavHostFragment หลักที่มีพ่อแม่รายเดียว และใช้พื้นที่เต็ม ที่มีส่วนย่อยต่างๆ ของปลายทางย่อยเมื่อผู้ใช้ไปยังส่วนต่างๆ แอปของคุณ

ใช้ FragmentManager

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

เมื่อผู้ใช้แตะปุ่ม "กลับ" ในอุปกรณ์หรือเมื่อคุณโทร FragmentManager.popBackStack() ธุรกรรมส่วนย่อยที่อยู่บนสุดจะปรากฏนอกกลุ่ม หากไม่มีส่วนอื่นอีก ธุรกรรมในสแต็ก และหากคุณไม่ได้ใช้ส่วนย่อยย่อย ข้อผิดพลาด "ย้อนกลับ" ลูกโป่งของกิจกรรม หากคุณกำลังใช้ส่วนย่อยย่อย โปรดดู สิ่งที่ควรพิจารณาเป็นพิเศษสำหรับส่วนย่อยที่เป็นเด็กและพี่น้อง

เมื่อคุณโทร addToBackStack() ในธุรกรรมหนึ่งๆ ธุรกรรมนั้นสามารถมีจำนวน การดำเนินการ เช่น การเพิ่มส่วนย่อยหลายรายการหรือการแทนที่ส่วนย่อยในส่วนย่อย คอนเทนเนอร์

เมื่อการสำรองข้อมูลเป็นกลุ่ม กลับกันเป็นปฏิกิริยาของอะตอมเดียว แต่ถ้าคุณมีข้อผูกมัด ธุรกรรมเพิ่มเติมก่อนการโทร popBackStack() และหาก ไม่ได้ใช้ addToBackStack() สำหรับธุรกรรม การดำเนินการเหล่านี้ ไม่ย้อนกลับ ดังนั้น ภายใน FragmentTransaction เดียว ให้หลีกเลี่ยง ธุรกรรมที่มีผลกระทบกับรายการสำรองกับธุรกรรมที่ไม่เกี่ยวข้อง

ทำธุรกรรม

หากต้องการแสดงส่วนย่อยภายในคอนเทนเนอร์เลย์เอาต์ ให้ใช้ FragmentManager เพื่อสร้าง FragmentTransaction ในธุรกรรมดังกล่าว คุณจะทำสิ่งต่อไปนี้ได้ ดำเนินการ add() หรือ replace() ดำเนินการกับคอนเทนเนอร์

ตัวอย่างเช่น FragmentTransaction แบบง่ายอาจมีลักษณะดังนี้

Kotlin

supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container)
   setReorderingAllowed(true)
   addToBackStack("name") // Name can be null
}

Java

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.fragment_container, ExampleFragment.class, null)
    .setReorderingAllowed(true)
    .addToBackStack("name") // Name can be null
    .commit();

ในตัวอย่างนี้ ExampleFragment จะแทนที่ส่วนย่อย หากมี ซึ่งก็คือ อยู่ในคอนเทนเนอร์เลย์เอาต์ที่ระบุโดย รหัส R.id.fragment_container การระบุคลาสของส่วนย่อยให้กับฟังก์ชัน replace() จะทำให้ FragmentManager จัดการการสร้างอินสแตนซ์โดยใช้ FragmentFactory ดูข้อมูลเพิ่มเติมได้ที่ส่วนระบุทรัพยากร Dependency ไปยัง Fragment

setReorderingAllowed(true) เพิ่มประสิทธิภาพการเปลี่ยนแปลงสถานะของส่วนย่อยที่เกี่ยวข้องในธุรกรรม เพื่อให้ภาพเคลื่อนไหวและการเปลี่ยนภาพ ทำงานได้อย่างถูกต้อง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ การนำทางด้วยภาพเคลื่อนไหวและการเปลี่ยน โปรดดู ธุรกรรมส่วนย่อย และ ไปยังส่วนต่างๆ ระหว่างส่วนย่อยโดยใช้ภาพเคลื่อนไหว

การโทร addToBackStack() ทำธุรกรรมไปยังแบ็กสแต็ก ผู้ใช้สามารถย้อนกลับ และนำส่วนก่อนหน้ากลับมาโดยแตะที่ หากคุณเพิ่มหรือนำส่วนย่อยหลายส่วนภายในส่วนเดียวออก ธุรกรรมทั้งหมด การดำเนินการเหล่านั้นจะถูกยกเลิกเมื่อสำรองข้อมูล โดนระเบิด ชื่อที่ไม่บังคับที่ระบุในการเรียกใช้ addToBackStack() จะให้ คุณสามารถกลับไปที่ธุรกรรมที่ต้องการได้โดยใช้ popBackStack()

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

ค้นหาส่วนย่อยที่มีอยู่

คุณจะได้รับการอ้างอิงส่วนย่อยปัจจุบันภายในคอนเทนเนอร์เลย์เอาต์ได้ โดยใช้ findFragmentById() ใช้ findFragmentById() เพื่อค้นหาส่วนย่อยตามรหัสที่ระบุเมื่อ พองขึ้นจาก XML หรือรหัสคอนเทนเนอร์เมื่อเพิ่มลงในไฟล์ FragmentTransaction ตัวอย่างเช่น

Kotlin

supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container)
   setReorderingAllowed(true)
   addToBackStack(null)
}
...
val fragment: ExampleFragment =
        supportFragmentManager.findFragmentById(R.id.fragment_container) as ExampleFragment

Java

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.fragment_container, ExampleFragment.class, null)
    .setReorderingAllowed(true)
    .addToBackStack(null)
    .commit();
...
ExampleFragment fragment =
        (ExampleFragment) fragmentManager.findFragmentById(R.id.fragment_container);

หรือสามารถกำหนดแท็กที่ไม่ซ้ำให้กับส่วนย่อยและรับ การอ้างอิงโดยใช้ findFragmentByTag() คุณกำหนดแท็กได้โดยใช้แอตทริบิวต์ XML android:tag ในส่วนย่อยที่ ถูกกำหนดภายในเลย์เอาต์ของคุณหรือในระหว่าง add() หรือ replace() ภายใน FragmentTransaction

Kotlin

supportFragmentManager.commit {
   replace<ExampleFragment>(R.id.fragment_container, "tag")
   setReorderingAllowed(true)
   addToBackStack(null)
}
...
val fragment: ExampleFragment =
        supportFragmentManager.findFragmentByTag("tag") as ExampleFragment

Java

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.fragment_container, ExampleFragment.class, null, "tag")
    .setReorderingAllowed(true)
    .addToBackStack(null)
    .commit();
...
ExampleFragment fragment = (ExampleFragment) fragmentManager.findFragmentByTag("tag");

สิ่งที่ต้องพิจารณาเป็นพิเศษสำหรับส่วนย่อยที่เป็นเด็กและพี่น้อง

มีเพียง FragmentManager เท่านั้นที่จะควบคุม Fragment Back Stack ได้ ณ เวลาใดเวลาหนึ่ง หากแอปแสดง Fragment ข้างเคียงหลายรายการบน พร้อมกัน หรือหากแอปของคุณใช้ Fragment ย่อย ก็ FragmentManager ได้รับการกำหนดให้จัดการการนำทางหลักของแอป

หากต้องการกำหนดส่วนย่อยการนำทางหลักภายในธุรกรรมส่วนย่อย โทรหา setPrimaryNavigationFragment() ในธุรกรรม โดยส่งผ่านในอินสแตนซ์ของแฟรกเมนต์ที่ childFragmentManager มีสิทธิ์ควบคุมหลัก

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

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

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

รองรับแบ็กสแต็กหลายจอ

ในบางกรณี แอปของคุณอาจต้องรองรับ Back Stack หลายส่วน ทั่วไป เช่น หากแอปใช้แถบนำทางด้านล่าง FragmentManager ช่วยให้ คุณสามารถรองรับสแต็กแบ็กสแต็กได้หลายสแต็กด้วย saveBackStack() และ restoreBackStack() วิธี วิธีการเหล่านี้ช่วยให้คุณสลับไปมา โดยการบันทึกสแต็กแบ็กสแต็กหนึ่ง และกู้คืนสแต็กอื่น

saveBackStack() ทำงานคล้ายกับการโทรหา popBackStack() ด้วยตัวเลือก พารามิเตอร์ name: ธุรกรรมที่ระบุและธุรกรรมทั้งหมดที่ตามมาใน ป๊อปซ้อนแล้ว ความแตกต่างคือ saveBackStack() บันทึก สถานะของส่วนย่อยทั้งหมดในป๊อปอัป ธุรกรรม

ตัวอย่างเช่น สมมติว่าก่อนหน้านี้คุณเพิ่มส่วนย่อยลงในสแต็กด้านหลังโดยใช้ คอมมิต FragmentTransaction โดยใช้ addToBackStack() ดังที่แสดงใน ตัวอย่างต่อไปนี้

Kotlin

supportFragmentManager.commit {
  replace<ExampleFragment>(R.id.fragment_container)
  setReorderingAllowed(true)
  addToBackStack("replacement")
}

Java

supportFragmentManager.beginTransaction()
  .replace(R.id.fragment_container, ExampleFragment.class, null)
  // setReorderingAllowed(true) and the optional string argument for
  // addToBackStack() are both required if you want to use saveBackStack()
  .setReorderingAllowed(true)
  .addToBackStack("replacement")
  .commit();

ในกรณีดังกล่าว คุณสามารถบันทึกธุรกรรมส่วนย่อยนี้ และสถานะของ ExampleFragment โดยโทรไปที่ saveBackStack():

Kotlin

supportFragmentManager.saveBackStack("replacement")

Java

supportFragmentManager.saveBackStack("replacement");

คุณสามารถเรียกใช้ restoreBackStack() ที่มีพารามิเตอร์ชื่อเดียวกันเพื่อกู้คืน ธุรกรรมที่เรียกผ่านหน้าต่างและสถานะส่วนย่อยที่บันทึกไว้ทั้งหมด ดังนี้

Kotlin

supportFragmentManager.restoreBackStack("replacement")

Java

supportFragmentManager.restoreBackStack("replacement");

ระบุทรัพยากร Dependency ไปยัง Fragment ของคุณ

เมื่อเพิ่ม Fragment คุณสามารถสร้างอินสแตนซ์ของ Fragment ด้วยตนเองและ เพิ่มลงใน FragmentTransaction

Kotlin

fragmentManager.commit {
    // Instantiate a new instance before adding
    val myFragment = ExampleFragment()
    add(R.id.fragment_view_container, myFragment)
    setReorderingAllowed(true)
}

Java

// Instantiate a new instance before adding
ExampleFragment myFragment = new ExampleFragment();
fragmentManager.beginTransaction()
    .add(R.id.fragment_view_container, myFragment)
    .setReorderingAllowed(true)
    .commit();

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

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

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

สมมติว่าคุณมี DessertsFragment ที่รับผิดชอบในการแสดง ของหวานยอดนิยมในบ้านเกิด และ DessertsFragment มีการขึ้นต่อกันกับคลาส DessertsRepository ที่ให้ ข้อมูลที่จำเป็นต่อการแสดง UI ที่ถูกต้องให้กับผู้ใช้

คุณอาจกำหนด DessertsFragment เพื่อกำหนดให้ต้องมี DessertsRepository ในเครื่องมือสร้าง

Kotlin

class DessertsFragment(val dessertsRepository: DessertsRepository) : Fragment() {
    ...
}

Java

public class DessertsFragment extends Fragment {
    private DessertsRepository dessertsRepository;

    public DessertsFragment(DessertsRepository dessertsRepository) {
        super();
        this.dessertsRepository = dessertsRepository;
    }

    // Getter omitted.

    ...
}

การใช้งาน FragmentFactory แบบง่ายๆ อาจดูคล้ายกับ ดังต่อไปนี้

Kotlin

class MyFragmentFactory(val repository: DessertsRepository) : FragmentFactory() {
    override fun instantiate(classLoader: ClassLoader, className: String): Fragment =
            when (loadFragmentClass(classLoader, className)) {
                DessertsFragment::class.java -> DessertsFragment(repository)
                else -> super.instantiate(classLoader, className)
            }
}

Java

public class MyFragmentFactory extends FragmentFactory {
    private DessertsRepository repository;

    public MyFragmentFactory(DessertsRepository repository) {
        super();
        this.repository = repository;
    }

    @NonNull
    @Override
    public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
        Class<? extends Fragment> fragmentClass = loadFragmentClass(classLoader, className);
        if (fragmentClass == DessertsFragment.class) {
            return new DessertsFragment(repository);
        } else {
            return super.instantiate(classLoader, className);
        }
    }
}

คลาสย่อยตัวอย่างนี้คือ FragmentFactory ซึ่งลบล้าง instantiate() เพื่อระบุตรรกะการสร้างส่วนย่อยที่กำหนดเองสำหรับ DessertsFragment ระบบจะจัดการคลาสของแฟรกเมนต์อื่นๆ ตามลักษณะการทำงานเริ่มต้นของ FragmentFactory จนถึง super.instantiate()

จากนั้น คุณสามารถกำหนด MyFragmentFactory เป็นการตั้งค่าเริ่มต้นเพื่อใช้เมื่อ การสร้างส่วนย่อยของแอปโดยการตั้งค่าพร็อพเพอร์ตี้ใน FragmentManager คุณต้องตั้งค่าพร็อพเพอร์ตี้นี้ก่อนกิจกรรม super.onCreate()เพื่อให้มั่นใจว่ามีการใช้ MyFragmentFactory เมื่อ การสร้างส่วนย่อยใหม่

Kotlin

class MealActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        supportFragmentManager.fragmentFactory = MyFragmentFactory(DessertsRepository.getInstance())
        super.onCreate(savedInstanceState)
    }
}

Java

public class MealActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        DessertsRepository repository = DessertsRepository.getInstance();
        getSupportFragmentManager().setFragmentFactory(new MyFragmentFactory(repository));
        super.onCreate(savedInstanceState);
    }
}

การตั้งค่า FragmentFactory ในส่วนการลบล้างกิจกรรม ตลอดทั้งลำดับชั้นส่วนย่อยของกิจกรรม กล่าวคือ childFragmentManager ของส่วนย่อยใดๆ ที่คุณเพิ่มจะใช้ ตั้งค่าส่วนย่อยเริ่มต้นที่นี่ เว้นแต่จะมีการลบล้างที่ระดับล่าง

ทดสอบกับ Fragmentfactor

ในสถาปัตยกรรมกิจกรรมเดียว ให้ทดสอบส่วนย่อยใน การแยกโดยใช้แอตทริบิวต์ FragmentScenario เนื่องจากคุณใช้ตรรกะ onCreate ที่กําหนดเองของ กิจกรรม คุณสามารถส่งผ่าน FragmentFactory เป็นอาร์กิวเมนต์ได้ ลงในการทดสอบ Fragment ดังที่ปรากฏในตัวอย่างต่อไปนี้

// Inside your test
val dessertRepository = mock(DessertsRepository::class.java)
launchFragment<DessertsFragment>(factory = MyFragmentFactory(dessertRepository)).onFragment {
    // Test Fragment logic
}

หากต้องการดูข้อมูลโดยละเอียดเกี่ยวกับขั้นตอนการทดสอบนี้และตัวอย่างทั้งหมด ดูทดสอบส่วนย่อยของคุณ