Cómo compilar un diseño de detalles de lista

Es un patrón de IU que consiste en un diseño de panel doble en el que un panel presenta una lista de elementos y otro panel muestra los detalles de los elementos seleccionados de la lista.

El patrón es particularmente útil para aplicaciones que proporcionan información información sobre elementos de grandes colecciones (por ejemplo, un cliente de correo electrónico) que tenga una lista de correos electrónicos y el contenido detallado de cada uno de ellos. Lista-detalles también se puede utilizar para rutas menos críticas, como dividir la aplicación preferencias en una lista de categorías con las preferencias para cada categoría en el panel de detalles.

Implementa el patrón de la IU con ListDetailPaneScaffold

ListDetailPaneScaffold es un elemento componible que simplifica la implementación de el patrón de lista-detalles de tu app. Un andamiaje de lista-detalles puede constar de hasta tres paneles: un panel de lista, un panel de detalles y un panel adicional opcional. El el andamiaje se encarga de los cálculos del espacio de pantalla. Cuando el tamaño de pantalla sea suficiente disponible, el panel de detalles se muestra junto al panel de lista. En pantallas pequeñas , el andamiaje cambia automáticamente a mostrar la lista o pantalla completa del panel de detalles.

Un panel de detalles que se muestra junto a la página de lista.
Figura 1: Cuando hay suficiente tamaño de pantalla disponible, el detalle junto al panel de lista.
Después de seleccionar un elemento, el panel de detalles ocupa toda la pantalla.
Figura 2: Cuando el tamaño de la pantalla es limitado, el panel de detalles (ya que se seleccionó un elemento) que ocupa todo el espacio.

Cómo declarar dependencias

ListDetailPaneScaffold es parte del diseño adaptable de Material 3. biblioteca.

Agrega las siguientes tres dependencias relacionadas al archivo build.gradle de tu app o módulo:

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'

  • adaptable: componentes básicos de bajo nivel, como HingeInfo y Posture
  • adaptive-layout: diseños adaptables, como ListDetailPaneScaffold y SupportingPaneScaffold
  • adaptive-navigation: Elementos que admiten composición para navegar dentro y entre paneles

Uso básico

Implementa ListDetailPaneScaffold de la siguiente manera:

  1. Usa una clase que represente el contenido que se seleccionará. Esta clase debería ser Parcelable para admitir el guardado y restableciendo el elemento de lista seleccionado. Usa kotlin-parcelize complemento para generar el código por ti.

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

  2. Crea un ThreePaneScaffoldNavigator con rememberListDetailPaneScaffoldNavigator y agrega un BackHandler. Esta Navigator se usa para desplazarse entre los paneles de lista, de detalles y adicionales. De declarando un tipo genérico, el navegador también rastrea el estado de la andamiaje (es decir, el objeto MyItem que se muestra). Como este tipo es parcelable, el navegador puede guardar y restablecer el estado para automáticamente los cambios de configuración. El BackHandler proporciona compatibilidad para navegar hacia atrás con el gesto atrás del sistema o . El comportamiento esperado del botón Atrás en una ListDetailPaneScaffold depende del tamaño de la ventana y del andamiaje actual valor. Si ListDetailPaneScaffold admite volver atrás con el el estado actual, canNavigateBack() es true, lo que habilita la BackHandler

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

  3. Pasa el scaffoldState del navigator al ListDetailPaneScaffold componible.

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

  4. Proporciona tu implementación del panel de lista a ListDetailPaneScaffold. Usa AnimatedPane para aplicar las animaciones de panel predeterminadas durante la navegación. Luego, utiliza ThreePaneScaffoldNavigator para navegar al panel de detalles ListDetailPaneScaffoldRole.Detail y muestra el elemento pasado.

    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. Incluye la implementación del panel de detalles en ListDetailPaneScaffold. Cuando se completa la navegación, currentDestination contiene el panel al que navegó la app, incluido el contenido que se muestra en el panel. El La propiedad content es del mismo tipo que se especificó en la llamada de recuerdo original (MyItem en este ejemplo), por lo que también puedes acceder a la propiedad para cualquier dato que debes mostrar.

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

Después de implementar los pasos anteriores, tu código debería ser similar al siguiente:

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)
            }
        }
    },
)