เลย์เอาต์แผงสนับสนุนช่วยให้ผู้ใช้มุ่งเน้นที่เนื้อหาหลักของแอปขณะแสดงข้อมูลสนับสนุนที่เกี่ยวข้อง ตัวอย่างเช่น แผงหลักอาจแสดงรายละเอียดเกี่ยวกับภาพยนตร์ ขณะที่แผงสนับสนุนแสดงรายการภาพยนตร์ที่คล้ายกัน ภาพยนตร์ของผู้กำกับคนเดียวกัน หรือผลงานที่มีนักแสดงคนเดียวกัน
ดูรายละเอียดเพิ่มเติมได้ที่หลักเกณฑ์เกี่ยวกับแผงสนับสนุนของ Material 3
ใช้แผงสนับสนุนที่มีโครงสร้างพื้นฐาน
NavigableSupportingPaneScaffold เป็น Composable ที่ช่วยให้การใช้เลย์เอาต์แผงสนับสนุนใน Jetpack Compose ง่ายขึ้น โดยจะรวม SupportingPaneScaffold และเพิ่มการนำทางในตัวและการจัดการการย้อนกลับที่คาดการณ์ได้
โครงสร้างของแผงสนับสนุนรองรับแผงได้สูงสุด 3 แผง ดังนี้
- แผงหลัก: แสดงเนื้อหาหลัก
- แผงสนับสนุน: ให้บริบทหรือเครื่องมือเพิ่มเติมที่เกี่ยวข้องกับแผงหลัก
- แผงเพิ่มเติม (ไม่บังคับ): ใช้สำหรับเนื้อหาเสริมเมื่อจำเป็น
โครงสร้างจะปรับตามขนาดหน้าต่าง ดังนี้
- ในหน้าต่างขนาดใหญ่ แผงหลักและแผงสนับสนุนจะปรากฏเคียงข้างกัน
ในหน้าต่างขนาดเล็ก จะมองเห็นได้ครั้งละ 1 แผงเท่านั้น โดยจะสลับไปตามการไปยังส่วนต่างๆ ของผู้ใช้
รูปที่ 1 เลย์เอาต์แผงสนับสนุน
เพิ่มทรัพยากร Dependency
NavigableSupportingPaneScaffold เป็นส่วนหนึ่งของไลบรารีเลย์เอาต์แบบปรับอัตโนมัติของ 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และPostureadaptive-layout: เลย์เอาต์แบบปรับขนาดได้ เช่น
ListDetailPaneScaffoldและSupportingPaneScaffoldadaptive-navigation: Composable สำหรับการไปยังส่วนต่างๆ ภายในและระหว่างแผง รวมถึงเลย์เอาต์แบบปรับเปลี่ยนได้ที่รองรับการไปยังส่วนต่างๆ โดยค่าเริ่มต้น เช่น
NavigableListDetailPaneScaffoldและNavigableSupportingPaneScaffold
ตรวจสอบว่าโปรเจ็กต์มี compose-material3-adaptive เวอร์ชัน 1.1.0-beta1 ขึ้นไป
เลือกใช้ท่าทางสัมผัสการย้อนกลับที่คาดการณ์ได้
หากต้องการเปิดใช้ภาพเคลื่อนไหวการย้อนกลับที่คาดการณ์ได้ใน Android 15 หรือต่ำกว่า คุณต้องเลือกใช้เพื่อรองรับท่าทางสัมผัสการย้อนกลับที่คาดการณ์ได้ หากต้องการเลือกใช้ ให้เพิ่ม android:enableOnBackInvokedCallback="true" ลงในแท็ก <application> หรือแท็ก <activity> แต่ละแท็กภายในไฟล์ AndroidManifest.xml
เมื่อแอปกำหนดเป้าหมายเป็น Android 16 (ระดับ API 36) ขึ้นไป ระบบจะเปิดใช้การย้อนกลับที่คาดการณ์ได้โดยค่าเริ่มต้น
สร้างตัวนำทาง
ในหน้าต่างขนาดเล็ก ระบบจะแสดงแผงทีละแผงเท่านั้น ดังนั้นให้ใช้ ThreePaneScaffoldNavigator เพื่อย้ายไปมาระหว่างแผง สร้างอินสแตนซ์ของเนวิเกเตอร์ด้วย rememberSupportingPaneScaffoldNavigator
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
ส่ง Navigator ไปยัง Scaffold
Scaffold ต้องใช้ ThreePaneScaffoldNavigator ซึ่งเป็นอินเทอร์เฟซที่แสดงสถานะของ Scaffold, ThreePaneScaffoldValue และ PaneScaffoldDirective
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
แผงหลักและแผงสนับสนุนเป็น Composable ที่มีเนื้อหาของคุณ ใช้ AnimatedPane เพื่อใช้ภาพเคลื่อนไหวของแผงเริ่มต้นระหว่างการนำทาง ใช้ค่า Scaffold เพื่อตรวจสอบว่าแผงสนับสนุนซ่อนอยู่หรือไม่ หากซ่อนอยู่ ให้แสดงปุ่มที่เรียกใช้ navigateTo(SupportingPaneScaffoldRole.Supporting) เพื่อแสดงแผงสนับสนุน
สำหรับหน้าจอขนาดใหญ่ ให้ใช้เมธอด ThreePaneScaffoldNavigator.navigateBack() เพื่อปิดแผงสนับสนุน โดยส่งค่าคงที่ BackNavigationBehavior.PopUntilScaffoldValueChange การเรียกใช้เมธอดนี้จะบังคับให้มีการจัดองค์ประกอบใหม่ของ NavigableSupportingPaneScaffold
ในระหว่างการจัดองค์ประกอบใหม่ ให้ตรวจสอบพร็อพเพอร์ตี้ ThreePaneScaffoldNavigator.currentDestination เพื่อพิจารณาว่าจะแสดงแผงสนับสนุนหรือไม่
ต่อไปนี้คือการติดตั้งใช้งาน Scaffold ที่สมบูรณ์
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() val backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { AnimatedPane( modifier = Modifier .safeContentPadding() .background(Color.Red) ) { if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier .wrapContentSize(), onClick = { scope.launch { scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { Column { // Allow users to dismiss the supporting pane. Use back navigation to // hide an expanded supporting pane. if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) { // Material design principles promote the usage of a right-aligned // close (X) button. IconButton( modifier = Modifier.align(Alignment.End).padding(16.dp), onClick = { scope.launch { scaffoldNavigator.navigateBack(backNavigationBehavior) } } ) { Icon(Icons.Default.Close, contentDescription = "Close") } } Text("Supporting pane") } } } )
แยกคอมโพสิเบิลของแผง
แยกแผงแต่ละแผงของ SupportingPaneScaffold ออกเป็น Composable ของตัวเองเพื่อให้ใช้ซ้ำและทดสอบได้ ใช้ ThreePaneScaffoldScope เพื่อเข้าถึง AnimatedPane หากต้องการภาพเคลื่อนไหวเริ่มต้น ดังนี้
@OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.MainPane( shouldShowSupportingPaneButton: Boolean, onNavigateToSupportingPane: () -> Unit, modifier: Modifier = Modifier, ) { AnimatedPane( modifier = modifier.safeContentPadding() ) { // Main pane content if (shouldShowSupportingPaneButton) { Button(onClick = onNavigateToSupportingPane) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } } @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.SupportingPane( scaffoldNavigator: ThreePaneScaffoldNavigator<Any>, modifier: Modifier = Modifier, backNavigationBehavior: BackNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange, ) { val scope = rememberCoroutineScope() AnimatedPane(modifier = Modifier.safeContentPadding()) { Column { // Allow users to dismiss the supporting pane. Use back navigation to // hide an expanded supporting pane. if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Expanded) { // Material design principles promote the usage of a right-aligned // close (X) button. IconButton( modifier = modifier.align(Alignment.End).padding(16.dp), onClick = { scope.launch { scaffoldNavigator.navigateBack(backNavigationBehavior) } } ) { Icon(Icons.Default.Close, contentDescription = "Close") } } Text("Supporting pane") } } }
การแยกแผงเป็น Composable ช่วยให้การใช้ SupportingPaneScaffold ง่ายขึ้น (เปรียบเทียบโค้ดต่อไปนี้กับการติดตั้งใช้งาน Scaffold ที่สมบูรณ์ในส่วนก่อนหน้า)
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane(scaffoldNavigator = scaffoldNavigator) }, )
หากต้องการควบคุมแง่มุมที่เฉพาะเจาะจงของ Scaffold มากขึ้น ให้พิจารณาใช้ SupportingPaneScaffold แทน NavigableSupportingPaneScaffold ซึ่งจะยอมรับ PaneScaffoldDirective และ ThreePaneScaffoldValue หรือ ThreePaneScaffoldState แยกกัน ความยืดหยุ่นนี้ช่วยให้คุณใช้ตรรกะที่กำหนดเองสำหรับระยะห่างระหว่างแผงและกำหนดจำนวนแผงที่ควรแสดงพร้อมกันได้ นอกจากนี้ คุณยังเปิดใช้การรองรับการย้อนกลับที่คาดการณ์ได้โดยเพิ่ม ThreePaneScaffoldPredictiveBackHandler
เพิ่ม ThreePaneScaffoldPredictiveBackHandler
แนบตัวแฮนเดิลการย้อนกลับที่คาดการณ์ได้ซึ่งรับอินสแตนซ์ตัวนำทาง Scaffold และระบุ backBehavior ซึ่งจะเป็นตัวกำหนดวิธีนำปลายทางออกจาก Back Stack ระหว่างการนำทางย้อนกลับ จากนั้นส่ง scaffoldDirective และ scaffoldState ไปยัง SupportingPaneScaffold ใช้โอเวอร์โหลดที่ยอมรับ
ThreePaneScaffoldState โดยส่งผ่าน scaffoldNavigator.scaffoldState
กำหนดแผงหลักและแผงสนับสนุนภายใน SupportingPaneScaffold ใช้ AnimatedPane สำหรับภาพเคลื่อนไหวของแผงเริ่มต้น
หลังจากทำตามขั้นตอนเหล่านี้แล้ว โค้ดของคุณควรมีลักษณะคล้ายกับโค้ดต่อไปนี้
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() ThreePaneScaffoldPredictiveBackHandler( navigator = scaffoldNavigator, backBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) SupportingPaneScaffold( directive = scaffoldNavigator.scaffoldDirective, scaffoldState = scaffoldNavigator.scaffoldState, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane(scaffoldNavigator = scaffoldNavigator) }, )