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

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

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

บานหน้าต่างรายละเอียดที่แสดงข้างหน้าเพจรายการ
รูปที่ 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")

ดึงดูด

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 ดังนั้น Navigator จึงสามารถบันทึกและกู้คืน สถานะเพื่อจัดการการเปลี่ยนแปลงการกำหนดค่า โดยอัตโนมัติได้

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

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

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

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

  1. เปลี่ยน defaultBackBehavior in 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
                        )

                    }
                }
            )
        }
    }