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

รูปแบบรายการ-รายละเอียดคือรูปแบบ UI ที่ประกอบด้วยเลย์เอาต์แบบ 2 บานหน้าต่าง โดยบานหน้าต่างหนึ่ง จะแสดงรายการไอเทม และอีกบานหน้าต่างจะแสดงรายละเอียดของไอเทมที่เลือก จากรายการ

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

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

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

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

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

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

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

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

ประกาศทรัพยากร 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")

Groovy

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

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

  1. ส่ง Navigator ไปยังฟังก์ชันที่ประกอบกันได้ NavigableListDetailPaneScaffold

  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
                        )

                    }
                }
            )
        }
    }