Daftar-detail adalah pola UI yang terdiri dari tata letak dua panel dengan satu panel menampilkan daftar item dan panel lainnya menampilkan detail item yang dipilih dari daftar.
Pola ini sangat berguna untuk aplikasi yang memberikan informasi mendalam tentang elemen koleksi besar, misalnya, program email yang memiliki daftar email dan konten terperinci setiap pesan email. Daftar-detail juga dapat digunakan untuk jalur yang tidak terlalu penting, seperti membagi preferensi aplikasi ke dalam daftar kategori dengan preferensi untuk setiap kategori di panel detail.
Mengimplementasikan pola UI dengan ListDetailPaneScaffold
ListDetailPaneScaffold
adalah composable yang menyederhanakan implementasi
pola daftar-detail di aplikasi Anda. Scaffold daftar-detail dapat terdiri dari hingga
tiga panel: panel daftar, panel detail, dan panel tambahan opsional. Scaffold menangani perhitungan ruang layar. Jika ukuran layar yang memadai
tersedia, panel detail akan ditampilkan di samping panel daftar. Pada ukuran
layar kecil, scaffold akan otomatis beralih untuk menampilkan
layar daftar atau panel detail dalam layar penuh.
Mendeklarasikan dependensi
ListDetailPaneScaffold
adalah bagian dari library adaptif Material 3.
Tambahkan dependensi untuk library dalam file build.gradle
bagi aplikasi
atau modul Anda:
implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-alpha07")
implementation("androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha07")
implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha07")
Penggunaan dasar
Berikut ini ilustrasi penggunaan dasar ListDetailPaneScaffold
:
Simpan item yang saat ini dipilih dari daftar dalam variabel status yang dapat berubah. Variabel menyimpan item yang akan ditampilkan di panel detail. Biasanya, Anda perlu menginisialisasi item yang saat ini dipilih dengan
null
, yang menunjukkan bahwa belum ada pilihan yang dibuat.class MyItem(val id: Int) { companion object { val Saver: Saver<MyItem?, Int> = Saver( { it?.id }, ::MyItem, ) } }
var selectedItem: MyItem? by rememberSaveable(stateSaver = MyItem.Saver) { mutableStateOf(null) }
Buat
ThreePaneScaffoldNavigator
denganrememberListDetailPaneScaffoldNavigator
, lalu tambahkanBackHandler
. Navigator ini digunakan untuk berpindah antara panel daftar, detail, dan tambahan, serta memberikan status ke scaffold.BackHandler
yang ditambahkan memberikan dukungan untuk menavigasi kembali menggunakan tombol atau gestur kembali sistem. Perilaku tombol kembali yang diharapkan untukListDetailPaneScaffold
bergantung pada ukuran jendela dan nilai scaffold saat ini. JikaListDetailPaneScaffold
dapat mendukung pengembalian dengan status saat ini,canNavigateBack()
akan menjaditrue
, yang mengaktifkanBackHandler
.val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
Teruskan
scaffoldState
darinavigator
yang Anda buat ke composableListDetailPaneScaffold
.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
Masukkan implementasi panel daftar Anda ke
ListDetailPaneScaffold
. Pastikan implementasi Anda menyertakan argumen callback untuk mengambil item yang baru dipilih. Saat callback ini dipicu, update variabel statusselectedItem
dan gunakanThreePaneScaffoldNavigator
untuk menampilkan panel detail (ListDetailPaneScaffoldRole.Detail
).ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane(Modifier) { MyList( onItemClick = { id -> // Set current item selectedItem = id // Switch focus to detail pane navigator.navigateTo(ListDetailPaneScaffoldRole.Detail) } ) } }, // ... )
Sertakan implementasi panel detail Anda di
ListDetailPaneScaffold
. Menampilkan konten detail hanya jikaselectedItem
bukan null.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane(Modifier) { selectedItem?.let { item -> MyDetails(item) } } }, )
Setelah menerapkan langkah-langkah di atas, kode Anda akan terlihat seperti ini:
// Currently selected item var selectedItem: MyItem? by rememberSaveable(stateSaver = MyItem.Saver) { mutableStateOf(null) } // Create the ListDetailPaneScaffoldState val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane(Modifier) { MyList( onItemClick = { id -> // Set current item selectedItem = id // Display the detail pane navigator.navigateTo(ListDetailPaneScaffoldRole.Detail) }, ) } }, detailPane = { AnimatedPane(Modifier) { // Show the detail pane content if selected item is available selectedItem?.let { item -> MyDetails(item) } } }, )