Bố cục ngăn chi tiết giúp người dùng tập trung vào nội dung chính của ứng dụng trong khi hiển thị thông tin chi tiết liên quan. Ví dụ: ngăn chính có thể hiển thị thông tin chi tiết về một bộ phim, trong khi ngăn phụ liệt kê các bộ phim tương tự, phim của cùng một đạo diễn hoặc tác phẩm có cùng diễn viên.
Để biết thêm thông tin chi tiết, hãy xem nguyên tắc về ngăn hỗ trợ Material 3.
Triển khai ngăn hỗ trợ bằng NavigableSupportingPaneScaffold
NavigableSupportingPaneScaffold
là một thành phần kết hợp giúp đơn giản hoá việc triển khai bố cục ngăn hỗ trợ trong Jetpack Compose. Thành phần này bao bọc SupportingPaneScaffold
và thêm tính năng điều hướng tích hợp sẵn cũng như tính năng xử lý thao tác quay lại theo dự đoán.
Cấu trúc ngăn hỗ trợ hỗ trợ tối đa 3 ngăn:
- Ngăn chính: Hiển thị nội dung chính.
- Ngăn hỗ trợ: Cung cấp thêm ngữ cảnh hoặc công cụ liên quan đến ngăn chính.
- Ngăn bổ sung (không bắt buộc): Dùng cho nội dung bổ sung khi cần.
Khung này thích ứng dựa trên kích thước cửa sổ:
- Trong cửa sổ lớn, ngăn chính và ngăn hỗ trợ sẽ xuất hiện cạnh nhau.
Trong cửa sổ nhỏ, mỗi lần chỉ hiển thị một ngăn, chuyển đổi khi người dùng di chuyển.
Hình 1. Bố cục ngăn hỗ trợ.
Thêm phần phụ thuộc
NavigableSupportingPaneScaffold
là một phần của thư viện bố cục thích ứng Material 3.
Thêm ba phần phụ thuộc có liên quan sau vào tệp build.gradle
của ứng dụng hoặc mô-đun:
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'
- thích ứng: Các khối xây dựng cấp thấp như
HingeInfo
vàPosture
- adaptive-layout: Bố cục thích ứng như
ListDetailPaneScaffold
vàSupportingPaneScaffold
- adaptive-navigation: Các thành phần kết hợp để điều hướng trong và giữa các ngăn, cũng như các bố cục thích ứng hỗ trợ điều hướng theo mặc định, chẳng hạn như
NavigableListDetailPaneScaffold
vàNavigableSupportingPaneScaffold
Đảm bảo dự án của bạn có compose-material3-adaptive phiên bản 1.1.0-beta1 trở lên.
Chọn sử dụng tính năng xem trước thao tác quay lại
Để bật ảnh động xem trước thao tác quay lại trong Android 15 trở xuống, bạn phải chọn sử dụng tính năng hỗ trợ cử chỉ xem trước thao tác quay lại. Để chọn sử dụng, hãy thêm android:enableOnBackInvokedCallback="true"
vào thẻ <application>
[hoặc android:enableOnBackInvokedCallback="true"
vào thẻ <application>
hoặc từng thẻ <activity>
trong tệp AndroidManifest.xml
.
Khi ứng dụng của bạn nhắm đến Android 16 (API cấp 36) trở lên, tính năng dự đoán thao tác quay lại sẽ được bật theo mặc định.
Tạo trình điều hướng
Trong cửa sổ nhỏ, mỗi lần chỉ hiển thị một ngăn, vì vậy, hãy sử dụng ThreePaneScaffoldNavigator
để di chuyển đến và đi từ các ngăn. Tạo một thực thể của trình điều hướng bằng rememberSupportingPaneScaffoldNavigator
.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Truyền trình điều hướng đến giàn giáo
Khung này yêu cầu ThreePaneScaffoldNavigator
là một giao diện đại diện cho trạng thái của khung, ThreePaneScaffoldValue
và PaneScaffoldDirective
.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
Ngăn chính và ngăn hỗ trợ là các thành phần kết hợp chứa nội dung của bạn. Sử dụng AnimatedPane
để áp dụng ảnh động ngăn mặc định trong quá trình điều hướng. Sử dụng giá trị của ngăn scaffolding để kiểm tra xem ngăn hỗ trợ có bị ẩn hay không; nếu có, hãy hiển thị một nút gọi navigateTo(SupportingPaneScaffoldRole.Supporting)
để hiển thị ngăn hỗ trợ.
Dưới đây là cách triển khai hoàn chỉnh của giàn giáo:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() 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()) { Text("Supporting pane") } } )
Trích xuất thành phần kết hợp ngăn
Trích xuất các ngăn riêng lẻ của SupportingPaneScaffold
vào các thành phần kết hợp riêng để có thể sử dụng lại và kiểm thử. Sử dụng ThreePaneScaffoldScope
để truy cập vào AnimatedPane
nếu bạn muốn sử dụng ảnh động mặc định:
@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( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
Việc trích xuất các ngăn thành các thành phần kết hợp sẽ đơn giản hoá việc sử dụng SupportingPaneScaffold
(so sánh nội dung sau với cách triển khai đầy đủ của giàn giáo trong phần trước):
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() }, )
Nếu bạn cần kiểm soát nhiều hơn đối với các khía cạnh cụ thể của ngăn xếp, hãy cân nhắc sử dụng SupportingPaneScaffold
thay vì NavigableSupportingPaneScaffold
. Phương thức này chấp nhận PaneScaffoldDirective
và ThreePaneScaffoldValue
hoặc ThreePaneScaffoldState
riêng biệt. Tính linh hoạt này cho phép bạn triển khai logic tuỳ chỉnh cho khoảng cách ngăn và xác định số lượng ngăn sẽ hiển thị đồng thời. Bạn cũng có thể bật tính năng hỗ trợ xem trước thao tác quay lại bằng cách thêm ThreePaneScaffoldPredictiveBackHandler
.
Thêm ThreePaneScaffoldPredictiveBackHandler
Đính kèm trình xử lý xem trước thao tác quay lại, lấy một thực thể trình điều hướng giàn giáo và chỉ định backBehavior
. Giá trị này xác định cách các đích đến được đẩy ra khỏi ngăn xếp lui trong quá trình điều hướng lui. Sau đó, truyền scaffoldDirective
và scaffoldState
đến SupportingPaneScaffold
. Sử dụng phương thức nạp chồng chấp nhận ThreePaneScaffoldState
, truyền vào scaffoldNavigator.scaffoldState
.
Xác định ngăn chính và ngăn hỗ trợ trong SupportingPaneScaffold
. Sử dụng AnimatedPane
cho ảnh động ngăn mặc định.
Sau khi triển khai các bước này, mã của bạn sẽ có dạng như sau:
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() }, )