Tworzenie układu ze szczegółami listy

Szczegóły listy to wzorzec interfejsu składający się z układu z 2 panelami, w którym jeden wyświetla listę elementów, a w kolejnym panelu wyświetlane są ich szczegóły. z listy.

Ten wzorzec jest szczególnie przydatny w aplikacjach, które zawierają szczegółowe informacje o elementach dużych kolekcji, np. klient poczty e-mail; z listą adresów e-mail i szczegółową treścią każdej z nich. Szczegółów listy można też używać w przypadku mniej krytycznych ścieżek, takich jak dzielenie aplikacji swoje preferencje na liście kategorii z preferencjami dla każdej z nich panelu szczegółów.

Zaimplementuj wzorzec interfejsu za pomocą interfejsu ListDetailPaneScaffold

ListDetailPaneScaffold to element kompozycyjny, który upraszcza implementację zgodnie ze wzorcem szczegółów listy w aplikacji. Ruszt związany ze szczegółami listy może się składać z 3 panele: lista, panel szczegółów oraz opcjonalny panel dodatkowy. scaffold obsługuje obliczenia miejsca na ekranie. Przy odpowiednim rozmiarze ekranu okienko szczegółów zostanie wyświetlone obok okienka listy. Na małym ekranie rusztowanie automatycznie przełączy się na wyświetlanie listy lub panelu szczegółów na pełnym ekranie.

Okienko szczegółów widoczne obok strony z listą.
Rysunek 1. Gdy dostępny jest wystarczający rozmiar ekranu, szczegóły widoczny obok okienka z listą.
.
Po wybraniu elementu panel szczegółów zajmie cały ekran.
Rys. 2. Gdy rozmiar ekranu jest ograniczony, okienko szczegółów (po wybraniu elementu) zajmuje całą przestrzeń.

Deklarowanie zależności

ListDetailPaneScaffold jest częścią układu adaptacyjnego Material 3

Aplikacja musi zawierać zależności od 3 powiązanych bibliotek Material 3:

  • Adaptacyjne – elementy składowe niskiego poziomu, np. HingeInfo i Posture
  • układ adaptacyjny – układy adaptacyjne, takie jak ListDetailPaneScaffold i SupportingPaneScaffold
    • adaptive-Navigation – elementy kompozycyjne do nawigacji w obrębie między panelami

Dodaj zależności do pliku build.gradle aplikacji lub modułu:

Kotlin


implementation("androidx.compose.material3.adaptive:adaptive:1.0.0-alpha12")
implementation("androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha12")
implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha12")

Odlotowe


implementation 'androidx.compose.material3.adaptive:adaptive:1.0.0-alpha12'
implementation 'androidx.compose.material3.adaptive:adaptive-layout:1.0.0-alpha12'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha12'

Podstawowe wykorzystanie

Wdróż ListDetailPaneScaffold w ten sposób:

  1. Użyj klasy, która reprezentuje treść do wyboru. Te zajęcia powinna mieć wartość Parcelable, aby obsługiwać zapisywanie i przywrócenie wybranej pozycji z listy. Wykorzystaj „parcelize” kotlin wtyczki, by wygenerować kod.

    @Parcelize
    class MyItem(val id: Int) : Parcelable

  2. Utwórz ThreePaneScaffoldNavigator z: rememberListDetailPaneScaffoldNavigator i dodaj BackHandler. Ten nawigator służy do poruszania się między listą, szczegółami i dodatkowymi panelami. Według zadeklarując typ ogólny, nawigator śledzi również stan scaffold (czyli wyświetlane jest MyItem). Ten typ jest parcelable, stan może zostać zapisany i przywrócony przez nawigator automatycznie obsługują zmiany konfiguracji. BackHandler umożliwia cofanie się za pomocą systemowego gestu cofania lub Przycisk Oczekiwane działanie przycisku Wstecz przez ListDetailPaneScaffold zależy od rozmiaru okna i aktualnego rusztowania . Jeśli ListDetailPaneScaffold obsługuje powrót z parametrem w bieżącym stanie, canNavigateBack() ma wartość true, co włącza BackHandler

    val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
    
    BackHandler(navigator.canNavigateBack()) {
        navigator.navigateBack()
    }

  3. Przekaż scaffoldState z przystanku navigator do ListDetailPaneScaffold kompozycyjne.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        // ...
    )

  4. Udostępnij w narzędziu ListDetailPaneScaffold implementację panelu listy. Używaj AnimatedPane aby zastosować domyślne animacje panelu podczas nawigacji. Następnie użyj ThreePaneScaffoldNavigator, aby przejść do panelu szczegółów. ListDetailPaneScaffoldRole.Detail i wyświetlić przekazany element.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            AnimatedPane {
                MyList(
                    onItemClick = { item ->
                        // Navigate to the detail pane with the passed item
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
                    }
                )
            }
        },
        // ...
    )

  5. Dołącz wdrożenie panelu szczegółów w narzędziu ListDetailPaneScaffold. Po zakończeniu nawigacji currentDestination będzie zawierać panel Do której udało się przejść aplikację, w tym do treści wyświetlanej w panelu. Właściwość content jest tego samego typu określonego w pierwotnym wywołaniu zapamiętania (w tym przykładzie MyItem), dzięki czemu możesz też uzyskać dostęp do usługi w przypadku dowolnych danych które chcesz wyświetlić.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane =
        // ...
        detailPane = {
            AnimatedPane {
                navigator.currentDestination?.content?.let {
                    MyDetails(it)
                }
            }
        },
    )

Po zaimplementowaniu powyższych kroków Twój kod powinien wyglądać mniej więcej tak:

val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()

BackHandler(navigator.canNavigateBack()) {
    navigator.navigateBack()
}

ListDetailPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    listPane = {
        AnimatedPane {
            MyList(
                onItemClick = { item ->
                    // Navigate to the detail pane with the passed item
                    navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
                },
            )
        }
    },
    detailPane = {
        AnimatedPane {
            // Show the detail pane content if selected item is available
            navigator.currentDestination?.content?.let {
                MyDetails(it)
            }
        }
    },
)