Szczegóły listy to wzorzec interfejsu użytkownika składający się z układu z 2 panelami, w którym jeden panel zawiera listę elementów, a inny zawiera szczegółowe informacje o elementach wybranych z listy.
Wzorzec jest szczególnie przydatny w aplikacjach, które dostarczają szczegółowe informacje o elementach dużych zbiorów, takich jak klient poczty e-mail z listą e-maili i szczegółową treścią każdej wiadomości. Szczegóły listy mogą być też używane w przypadku mniej ważnych ścieżek, na przykład do dzielenia ustawień aplikacji na listę kategorii z preferencjami dla każdej kategorii w panelu szczegółów.
Zaimplementuj wzorzec interfejsu za pomocą funkcji ListDetailPaneScaffold
ListDetailPaneScaffold
to funkcja kompozycyjna, która upraszcza implementację wzorca szczegółów listy w aplikacji. Szkielet szczegółów listy może się składać z maksymalnie 3 paneli: panelu listy, panelu szczegółów i opcjonalnego panelu dodatkowego. Platforma obsługuje obliczenia przestrzeni ekranu. Gdy dostępny jest wystarczający rozmiar ekranu, obok panelu z listą wyświetla się panel szczegółów. Na małych ekranach automatycznie przełącza się ono na wyświetlanie listy lub panelu szczegółów na pełnym ekranie.
Deklarowanie zależności
ListDetailPaneScaffold
jest częścią biblioteki adaptacyjnej Material 3.
Dodaj zależność dla biblioteki w pliku build.gradle
aplikacji lub modułu:
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")
Podstawowe użycie
Poniżej pokazujemy podstawowe użycie ListDetailPaneScaffold
:
Zapisać aktualnie wybrany element z listy w zmiennej zmiennej stanu. Zmienna zawiera element, który ma zostać wyświetlony w panelu szczegółów. Zwykle do zainicjowania wybranego obecnie elementu najlepiej nadaje się parametr
null
, co oznacza, że jeszcze nie wybrano żadnego elementu.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) }
Utwórz
ThreePaneScaffoldNavigator
zrememberListDetailPaneScaffoldNavigator
i dodajBackHandler
. Ten nawigator służy do przechodzenia między panelami z listą, szczegółami i dodatkowymi panelami oraz przekazywaniem stanu do rusztu. DodanyBackHandler
zapewnia obsługę przechodzenia do tyłu za pomocą systemowego gestu lub przycisku Wstecz. Oczekiwane działanie przycisku Wstecz w przypadku elementuListDetailPaneScaffold
zależy od rozmiaru okna i bieżącej wartości scaffold. JeśliListDetailPaneScaffold
obsługuje przywrócenie do obecnego stanu,canNavigateBack()
ma wartośćtrue
, co powoduje włączenieBackHandler
.val navigator = rememberListDetailPaneScaffoldNavigator<Nothing>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
Przekaż
scaffoldState
z utworzonegonavigator
elementu do funkcji kompozycyjnejListDetailPaneScaffold
.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
Prześlij implementację panelu listy do
ListDetailPaneScaffold
. Upewnij się, że implementacja zawiera argument wywołania zwrotnego do przechwytywania nowo wybranego elementu. Po wywołaniu tego wywołania zwrotnego zaktualizuj zmienną stanuselectedItem
i użyj poleceniaThreePaneScaffoldNavigator
, aby wyświetlić panel szczegółów (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) } ) } }, // ... )
Umieść implementację panelu szczegółów w
ListDetailPaneScaffold
. Wyświetl szczegóły tylko wtedy, gdyselectedItem
nie ma wartości null.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane(Modifier) { selectedItem?.let { item -> MyDetails(item) } } }, )
Po wykonaniu powyższych czynności kod powinien wyglądać mniej więcej tak:
// 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) } } }, )