Tata letak panel pendukung membuat pengguna tetap fokus pada konten utama aplikasi sambil menampilkan informasi pendukung yang relevan. Misalnya, panel utama mungkin menampilkan detail tentang film, sedangkan panel pendukung mencantumkan film serupa, film dari sutradara yang sama, atau karya yang menampilkan aktor yang sama.
Untuk mengetahui detail selengkapnya, lihat Panduan panel pendukung Material 3.
Mengimplementasikan panel pendukung dengan scaffold
NavigableSupportingPaneScaffold adalah composable yang menyederhanakan
penerapan tata letak panel pendukung di Jetpack Compose. Class ini menggabungkan
SupportingPaneScaffold serta menambahkan navigasi bawaan dan penanganan kembali
prediktif.
Scaffold panel pendukung mendukung hingga tiga panel:
- Panel utama: Menampilkan konten utama.
- Panel pendukung: Memberikan konteks atau alat tambahan yang terkait dengan panel utama.
- Panel tambahan (opsional): Digunakan untuk konten tambahan jika diperlukan.
Scaffold beradaptasi berdasarkan ukuran jendela:
- Di jendela besar, panel utama dan pendukung muncul berdampingan.
Di jendela kecil, hanya satu panel yang terlihat dalam satu waktu, yang beralih saat pengguna melakukan navigasi.
Gambar 1. Tata letak panel pendukung.
Menambahkan dependensi
NavigableSupportingPaneScaffold adalah bagian dari library tata letak adaptif Material 3.
Tambahkan tiga dependensi terkait berikut ke file build.gradle aplikasi atau modul Anda:
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: Elemen penyusun tingkat rendah seperti
HingeInfodanPostureadaptive-layout: Tata letak adaptif seperti
ListDetailPaneScaffolddanSupportingPaneScaffoldadaptive-navigation: Composable untuk menavigasi di dalam dan di antara panel, serta tata letak adaptif yang mendukung navigasi secara default seperti
NavigableListDetailPaneScaffolddanNavigableSupportingPaneScaffold
Pastikan project Anda menyertakan compose-material3-adaptive versi 1.1.0-beta1 atau yang lebih tinggi.
Memilih untuk menggunakan gestur kembali prediktif
Untuk mengaktifkan animasi kembali prediktif di Android 15 atau yang lebih lama, Anda harus mengaktifkan
dukungan untuk gestur kembali prediktif. Untuk memilih ikut serta, tambahkan
android:enableOnBackInvokedCallback="true" ke tag <application> atau
tag <activity> individual dalam file AndroidManifest.xml Anda.
Setelah aplikasi Anda menargetkan Android 16 (level API 36) atau yang lebih tinggi, kembali prediktif akan diaktifkan secara default.
Membuat navigator
Di jendela kecil, hanya satu panel yang ditampilkan dalam satu waktu, jadi gunakan
ThreePaneScaffoldNavigator untuk berpindah ke dan dari panel. Buat instance
navigator dengan rememberSupportingPaneScaffoldNavigator.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Meneruskan navigator ke scaffold
Scaffold memerlukan ThreePaneScaffoldNavigator yang merupakan antarmuka
yang mewakili status scaffold, ThreePaneScaffoldValue, dan
PaneScaffoldDirective.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
Panel utama dan panel pendukung adalah composable yang berisi konten Anda. Gunakan
AnimatedPane untuk menerapkan animasi panel default selama navigasi. Gunakan
nilai scaffold untuk memeriksa apakah panel pendukung disembunyikan; jika ya,
tampilkan tombol yang memanggil
navigateTo(SupportingPaneScaffoldRole.Supporting) untuk menampilkan
panel pendukung.
Untuk layar besar, gunakan metode ThreePaneScaffoldNavigator.navigateBack()
untuk menutup panel pendukung, dengan meneruskan
konstanta BackNavigationBehavior.PopUntilScaffoldValueChange. Memanggil metode ini akan memaksa rekomposisi NavigableSupportingPaneScaffold.
Selama rekomposisi, periksa
properti ThreePaneScaffoldNavigator.currentDestination untuk menentukan
apakah akan menampilkan panel pendukung.
Berikut adalah implementasi lengkap 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") } } } )
Mengekstrak composable panel
Ekstrak setiap panel SupportingPaneScaffold ke dalam composable-nya sendiri
agar dapat digunakan kembali dan diuji. Gunakan ThreePaneScaffoldScope
untuk mengakses AnimatedPane jika Anda menginginkan animasi default:
@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") } } }
Mengekstrak panel ke dalam composable akan menyederhanakan penggunaan
SupportingPaneScaffold (bandingkan kode berikut dengan implementasi lengkap
scaffold di bagian sebelumnya):
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) }, )
Jika Anda memerlukan kontrol lebih besar atas aspek tertentu dari scaffold, pertimbangkan untuk menggunakan
SupportingPaneScaffold, bukan NavigableSupportingPaneScaffold. Fungsi ini
menerima PaneScaffoldDirective dan ThreePaneScaffoldValue atau
ThreePaneScaffoldState secara terpisah. Fleksibilitas ini memungkinkan Anda menerapkan
logika kustom untuk penspasian panel dan menentukan jumlah panel yang harus ditampilkan
secara bersamaan. Anda juga dapat mengaktifkan dukungan kembali prediktif dengan menambahkan
ThreePaneScaffoldPredictiveBackHandler.
Tambahkan ThreePaneScaffoldPredictiveBackHandler
Lampirkan pengendali kembali prediktif yang menggunakan instance navigator scaffold dan
tentukan backBehavior. Hal ini menentukan cara tujuan dikeluarkan dari
data sebelumnya selama navigasi kembali. Kemudian, teruskan scaffoldDirective dan
scaffoldState ke SupportingPaneScaffold. Gunakan overload yang menerima
ThreePaneScaffoldState, dengan meneruskan scaffoldNavigator.scaffoldState.
Tentukan panel utama dan pendukung dalam SupportingPaneScaffold. Gunakan
AnimatedPane untuk animasi panel default.
Setelah Anda menerapkan langkah-langkah ini, kode Anda akan terlihat seperti berikut:
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) }, )