สร้างเลย์เอาต์รายละเอียดรายการ

รายละเอียดรายการเป็นรูปแบบ UI ที่ประกอบด้วยเลย์เอาต์แบบแยกหน้าจอ โดยแผงหนึ่งจะแสดงรายการ และอีกแผงหนึ่งจะแสดงรายละเอียดของรายการที่เลือกจากรายการนั้น

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

แผงรายละเอียดที่แสดงพร้อมกับหน้ารายการ
รูปที่ 1 เมื่อมีขนาดหน้าจอเพียงพอ แผงรายละเอียดจะแสดงข้างแผงรายการ
หลังจากเลือกรายการแล้ว แผงรายละเอียดจะแสดงเต็มหน้าจอ
รูปที่ 2 เมื่อขนาดหน้าจอมีจำกัด แผงรายละเอียด (เนื่องจากมีการเลือกรายการ) จะใช้พื้นที่ทั้งหมด

ใช้รูปแบบรายละเอียดรายการด้วย NavigableListDetailPaneScaffold

NavigableListDetailPaneScaffold เป็น Composable ที่ช่วยให้การติดตั้งใช้งานเลย์เอาต์แบบรายละเอียดรายการใน Jetpack Compose ง่ายขึ้น โดยจะรวม ListDetailPaneScaffold และเพิ่มการนำทางในตัวและภาพเคลื่อนไหวของการย้อนกลับที่คาดการณ์ได้

โครงสร้างรายละเอียดรายการรองรับแผงได้สูงสุด 3 แผง ดังนี้

  1. แผงรายการ: แสดงคอลเล็กชันของรายการต่างๆ
  2. แผงรายละเอียด: แสดงรายละเอียดของรายการที่เลือก
  3. แผงเพิ่มเติม (ไม่บังคับ): ให้บริบทเพิ่มเติมเมื่อจำเป็น

โครงสร้างจะปรับตามขนาดหน้าต่าง ดังนี้

  • ในหน้าต่างขนาดใหญ่ รายการและแผงรายละเอียดจะปรากฏเคียงข้างกัน
  • ในหน้าต่างขนาดเล็ก จะมองเห็นได้ครั้งละ 1 แผงเท่านั้น โดยจะสลับไปมาเมื่อผู้ใช้ไปยังส่วนต่างๆ

ประกาศทรัพยากร Dependency

NavigableListDetailPaneScaffold เป็นส่วนหนึ่งของไลบรารีการนำทางแบบปรับอัตโนมัติของ Material 3

เพิ่มทรัพยากร Dependency ที่เกี่ยวข้อง 3 รายการต่อไปนี้ลงในไฟล์ build.gradle ของแอปหรือโมดูล

Kotlin

implementation("androidx.compose.material3.adaptive:adaptive")
implementation("androidx.compose.material3.adaptive:adaptive-layout")
implementation("androidx.compose.material3.adaptive:adaptive-navigation")

ดึงดูด

implementation 'androidx.compose.material3.adaptive:adaptive'
implementation 'androidx.compose.material3.adaptive:adaptive-layout'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
  • adaptive: องค์ประกอบระดับต่ำ เช่น HingeInfo และ Posture
  • adaptive-layout: เลย์เอาต์แบบปรับขนาดได้ เช่น ListDetailPaneScaffold และ SupportingPaneScaffold
  • adaptive-navigation: Composable สำหรับการไปยังส่วนต่างๆ ภายในและระหว่างแผง รวมถึงเลย์เอาต์แบบปรับเปลี่ยนได้ที่รองรับการไปยังส่วนต่างๆ โดยค่าเริ่มต้น เช่น NavigableListDetailPaneScaffold และ NavigableSupportingPaneScaffold

ตรวจสอบว่าโปรเจ็กต์มี compose-material3-adaptive เวอร์ชัน 1.1.0-beta1 ขึ้นไป

เลือกใช้ท่าทางสัมผัสการย้อนกลับที่คาดการณ์ได้

หากต้องการเปิดใช้ภาพเคลื่อนไหวการย้อนกลับที่คาดการณ์ได้ใน Android 15 หรือต่ำกว่า คุณต้องเลือกใช้เพื่อรองรับท่าทางสัมผัสการย้อนกลับที่คาดการณ์ได้ หากต้องการเลือกใช้ ให้เพิ่ม android:enableOnBackInvokedCallback="true" ลงในแท็ก <application> หรือแท็ก <activity> แต่ละแท็กภายในไฟล์ AndroidManifest.xml ดูข้อมูลเพิ่มเติมได้ที่เลือกใช้ท่าทางสัมผัสการย้อนกลับที่คาดการณ์ได้

เมื่อแอปกำหนดเป้าหมายเป็น Android 16 (ระดับ API 36) ขึ้นไป ระบบจะเปิดใช้การย้อนกลับที่คาดการณ์ได้โดยค่าเริ่มต้น

การใช้งานพื้นฐาน

ใช้ NavigableListDetailPaneScaffold ดังนี้

  1. ใช้คลาสที่แสดงถึงเนื้อหาที่เลือก ใช้คลาส Parcelable เพื่อรองรับการบันทึกและกู้คืนรายการที่เลือก ใช้ปลั๊กอิน kotlin-parcelize เพื่อสร้างโค้ดให้คุณ
  2. สร้าง ThreePaneScaffoldNavigator ด้วย rememberListDetailPaneScaffoldNavigator

เครื่องมือนำทางนี้ใช้เพื่อย้ายไปมาระหว่างแผงรายการ แผงรายละเอียด และแผงเพิ่มเติม เมื่อประกาศประเภททั่วไป ตัวนำทางจะติดตามสถานะของ Scaffold ด้วย (นั่นคือ MyItem ใดที่แสดงอยู่) เนื่องจากประเภทนี้เป็นแบบ Parcelable จึงสามารถบันทึกและกู้คืนสถานะได้โดย Navigator เพื่อจัดการการเปลี่ยนแปลงการกำหนดค่าโดยอัตโนมัติ

  1. ส่ง Navigator ไปยัง NavigableListDetailPaneScaffold Composable

  2. ระบุการติดตั้งใช้งานแผงรายการให้กับ NavigableListDetailPaneScaffold ใช้ AnimatedPane เพื่อใช้ภาพเคลื่อนไหวของแผงเริ่มต้นระหว่างการไปยังส่วนต่างๆ จากนั้นใช้ ThreePaneScaffoldNavigator เพื่อไปยังแผงรายละเอียด ListDetailPaneScaffoldRole.Detail และแสดงรายการที่ส่งมา

  3. รวมการติดตั้งใช้งานแผงรายละเอียดใน NavigableListDetailPaneScaffold

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

  1. คุณสามารถเปลี่ยน defaultBackBehavior ใน NavigableListDetailPaneScaffold ได้ (ไม่บังคับ) โดยค่าเริ่มต้น NavigableListDetailPaneScaffold จะใช้ PopUntilScaffoldValueChange สำหรับ defaultBackBehavior

หากแอปของคุณต้องใช้รูปแบบการนำทางย้อนกลับที่แตกต่างออกไป คุณสามารถลบล้างลักษณะการทำงานนี้ได้โดยระบุตัวเลือก BackNavigationBehavior อื่น

BackNavigationBehavior ตัวเลือก

ส่วนต่อไปนี้ใช้ตัวอย่างของแอปอีเมลที่มีรายการอีเมลในแผงหนึ่งและมุมมองแบบละเอียดในอีกแผงหนึ่ง

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

ลองดูตัวอย่างต่อไปนี้

  • หลายแผง: คุณกำลังดูอีเมล (รายการที่ 1) ในแผงรายละเอียด การคลิกอีเมลอื่น (รายการที่ 2) จะอัปเดตแผงรายละเอียด แต่แผงรายการและแผงรายละเอียดจะยังคงปรากฏอยู่ การกดกลับอาจทำให้คุณออกจากแอปหรือขั้นตอนการนำทางปัจจุบัน
  • แผงเดียว: คุณดูรายการที่ 1 แล้วดูรายการที่ 2 การกดกลับจะนำคุณกลับไปยังแผงรายการอีเมลโดยตรง

ใช้ตัวเลือกนี้เมื่อต้องการให้ผู้ใช้รับรู้ถึงการเปลี่ยนเลย์เอาต์ที่แตกต่างกันด้วยการดำเนินการย้อนกลับแต่ละครั้ง

ภาพแสดงการเปลี่ยนแปลงค่าการนําทางในแผงเลย์เอาต์ต่างๆ
PopUntilContentChange

ลักษณะการทำงานนี้จะจัดลำดับความสำคัญของเนื้อหาที่แสดง หากคุณดูรายการที่ 1 แล้วดูรายการที่ 2 การกดปุ่มย้อนกลับจะเปลี่ยนกลับไปเป็นรายการที่ 1 ไม่ว่าเลย์เอาต์จะเป็นอย่างไร

ลองดูตัวอย่างต่อไปนี้

  • หลายแผง: คุณดูรายการที่ 1 ในแผงรายละเอียด แล้วคลิกรายการที่ 2 ในรายการ แผงรายละเอียดจะอัปเดต การกดปุ่มย้อนกลับจะคืนค่าแผงรายละเอียดเป็นรายการที่ 1
  • หน้าต่างเดียว: เนื้อหาจะเปลี่ยนกลับไปเป็นแบบเดิม

ใช้ตัวเลือกนี้เมื่อผู้ใช้คาดหวังว่าจะกลับไปยังเนื้อหาที่ดูก่อนหน้านี้ด้วยการดำเนินการย้อนกลับ

การเปลี่ยนระหว่างแผงรายละเอียด 2 แผง
PopUntilCurrentDestinationChange

ลักษณะการทำงานนี้จะแสดง Back Stack จนกว่าปลายทางการนำทางปัจจุบันจะเปลี่ยนแปลง ซึ่งจะมีผลกับทั้งเลย์เอาต์แบบแผงเดียวและหลายแผงเท่าๆ กัน

ลองดูตัวอย่างต่อไปนี้

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

ใช้ตัวเลือกนี้เมื่อการรักษาภาพที่ชัดเจนของการนําทางปัจจุบันเป็นสิ่งสําคัญต่อประสบการณ์ของผู้ใช้

การไปยังส่วนต่างๆ ระหว่างแผงรายละเอียดและแผงรายการ
PopLatest

ตัวเลือกนี้จะนำเฉพาะปลายทางล่าสุดออกจาก Backstack ใช้ตัวเลือกนี้สำหรับการนำทางย้อนกลับโดยไม่ข้ามสถานะกลาง

หลังจากทำตามขั้นตอนเหล่านี้แล้ว โค้ดของคุณควรมีลักษณะคล้ายกับโค้ดต่อไปนี้

NavigableListDetailPaneScaffold(
    navigator = navigator,
    listPane = {
        AnimatedPane {
            ListContent(
                words = sampleWords,
                selectionState = navigator.currentDestination?.contentKey?.let {
                    SelectionVisibilityState.ShowSelection(it)
                } ?: SelectionVisibilityState.NoSelection,
                onWordClick = { word ->
                    scope.launch {
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, word)
                    }
                },
                animatedVisibilityScope = this@AnimatedPane,
                sharedTransitionScope = this@SharedTransitionLayout
            )
        }
    },
    detailPane = {
        AnimatedPane {
            DetailContent(
                definedWord = navigator.currentDestination?.contentKey,
                animatedVisibilityScope = this@AnimatedPane,
                sharedTransitionScope = this@SharedTransitionLayout,
                onClosePane = {
                    scope.launch {
                        navigator.navigateBack(
                            backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange
                        )

                    }
                }
            )
        }
    }