Diseños canónicos

Los diseños canónicos son diseños versátiles y comprobados que proporcionan una experiencia del usuario óptima en una variedad de factores de forma.

Representación de dispositivos con pantalla grande que muestran los diseños canónicos

Los diseños canónicos son compatibles con teléfonos de pantalla pequeña, así como con tablets, plegables y dispositivos ChromeOS. Derivados de la guía de Material Design, los diseños son estéticos y funcionales.

El framework de Android incluye componentes especializados que hacen que la implementación de los diseños sea sencilla y confiable.

Los diseños canónicos crean IUs atractivas y que mejoran la productividad, lo que constituye la base de apps excelentes.

Detalles de lista

Estructura del diseño de lista y detalles

El diseño de lista y detalles les permite a los usuarios explorar las listas de elementos que tienen información descriptiva, explicativa o de otro tipo: los detalles del elemento.

El diseño divide la ventana de la app en dos paneles paralelos: uno para la lista y otro para los detalles. Los usuarios seleccionan elementos de la lista para ver sus detalles. Los vínculos directos en los detalles muestran contenido adicional en el panel de detalles.

Las pantallas de ancho expandido (consulta Usa clases de tamaño de ventana) admiten la lista y los detalles al mismo tiempo. La selección de un elemento de lista actualiza el panel de detalles para mostrar el contenido relacionado del elemento seleccionado.

Las pantallas de ancho mediano y compacto muestran la lista o los detalles, según la interacción del usuario con la app. Cuando solo se ve la lista, la selección de un elemento muestra los detalles en lugar de la lista. Cuando solo se vean los detalles, se volverá a mostrar la lista si se presiona el botón Atrás.

Los cambios de configuración, como la orientación del dispositivo o el tamaño de la ventana de la app, pueden modificar la clase de tamaño de la ventana de la pantalla. Un diseño de lista-detalles responde en consecuencia y mantiene el estado de la app de la siguiente manera:

  • Si una pantalla de ancho expandido que muestra los paneles de lista y de detalles se reduce a tamaño mediano o compacto, el panel de detalles permanece visible y el panel de lista se oculta.
  • Si una pantalla de ancho mediano o compacto tiene solo el panel de detalles visible y la clase de tamaño de ventana se expande, la lista y los detalles se muestran juntos, y la lista indica que el elemento correspondiente al contenido en el panel de detalles está seleccionado.
  • Si una pantalla de ancho mediano o compacto tiene solo el panel de lista visible y se expande, se mostrarán juntos la lista y un panel de detalles de marcador de posición.

El diseño de lista-detalles es ideal para apps de mensajería, administradores de contactos, navegadores de contenido multimedia interactivos o cualquier app en la que el contenido se pueda organizar como una lista de elementos que revelan información adicional.

Figura 1: App de mensajería que muestra una lista de conversaciones y los detalles de una conversación seleccionada

Implementación

El paradigma declarativo de Compose admite la lógica de clase de tamaño de ventana que determina si se muestran los paneles de lista y de detalles al mismo tiempo (cuando se expande la clase de tamaño de ancho de ventana) o solo el panel de lista o de detalles (cuando la clase de tamaño de ventana de ancho es mediana o compacta).

Para garantizar el flujo unidireccional de datos, eleva todo el estado, lo que incluye la clase de tamaño de ventana actual y los detalles del elemento de lista seleccionado (si corresponde), de modo que todos los elementos de componibilidad tengan acceso a los datos y puedan renderizarse sin problemas.

Cuando se muestre solo el panel de detalles en tamaños de ventana pequeños, agrega BackHandler para quitar el panel de detalles y mostrar solo el panel de lista. BackHandler no forma parte de la navegación general de la app, ya que el controlador depende de la clase de tamaño de ventana y del estado de detalles seleccionado.

ListDetailPaneScaffold es un elemento de componibilidad de alto nivel que simplifica la implementación de diseños de lista-detalles. Controla automáticamente la lógica del panel según las clases de tamaño de ventana y admite la navegación entre paneles.

A continuación, se muestra una implementación mínima con ListDetailPaneScaffold:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MyListDetailPaneScaffold() {
    val navigator = rememberListDetailPaneScaffoldNavigator()
    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            // Listing Pane
        },
        detailPane = {
            // Details Pane
        }
    )
}

Estos son los componentes clave de este ejemplo:

  • rememberListDetailPaneScaffoldNavigator: Crea un navegador para administrar la navegación entre los paneles de lista y de detalles.
  • listPane: Muestra la lista de elementos.
  • detailPane: Muestra el contenido de un elemento seleccionado.

Para obtener ejemplos de implementación detallados, consulta lo siguiente:

Feed

Estructura del diseño de feed

Un diseño de feed dispone elementos de contenido equivalentes en una cuadrícula configurable para permitir una visualización rápida y conveniente de una gran cantidad de contenido.

El tamaño y la posición establecen relaciones entre los elementos de contenido.

Los grupos de contenido se crean al hacer que los elementos tengan el mismo tamaño y posicionarlos juntos. Para atraer la atención a los elementos, estos deben ser más grandes que los cercanos.

Las tarjetas y las listas son componentes comunes de los diseños de feed.

Un diseño de feed admite pantallas de casi cualquier tamaño porque la cuadrícula se puede adaptar de una sola columna de desplazamiento a un feed de varias columnas de desplazamiento de contenido.

Los feeds son especialmente adecuados para las apps de noticias y redes sociales.

Figura 2: App de redes sociales que muestra publicaciones en tarjetas de diferentes tamaños

Implementación

Feed 包含大量内容元素,这些内容元素位于一个纵向滚动容器中,而该容器采用网格布局。延迟列表可高效地在列或行中呈现大量的项。延迟网格以网格形式呈现项,支持配置项的大小和 span。

根据可用的显示区域配置网格布局的列,以设置网格项允许的最小宽度。定义网格项时,只需调整列 span 即可让某些项比其他项更为醒目。

对于部分标题、分隔线或要占据 Feed 的整个宽度的其他项,请使用 maxLineSpan 占据布局的整个宽度。

如果较小宽度的显示屏没有足够的空间来显示一个以上的列,LazyVerticalGrid 就会像 LazyColumn 一样运行。

下面是使用 LazyVerticalGrid 的最小实现:

@Composable
fun MyFeed(names: List<String>) {
    LazyVerticalGrid(
        // GridCells.Adaptive automatically adapts column count based on available width
        columns = GridCells.Adaptive(minSize = 180.dp),
    ) {
        items(names) { name ->
            Text(name)
        }
    }
}

自适应 Feed 的关键在于 columns 配置。 GridCells.Adaptive(minSize = 180.dp) 创建一个网格,其中每列至少为 180.dp 宽。然后,网格会显示尽可能多的列,以适应可用空间。

如需查看示例实现,请参阅使用 Compose 构建 Feed 示例

Panel complementario

Esquema de página del diseño de panel complementario.

El diseño de panel complementario organiza el contenido de la app en áreas de visualización principales y secundarias.

El área de visualización principal ocupa la mayor parte de la ventana de la app (por lo general, alrededor de dos tercios) y tiene el contenido principal. El área de visualización secundaria es un panel que ocupa el resto de la ventana de la app y presenta contenido complementario del contenido principal.

Los diseños de panel complementario funcionan bien en pantallas de ancho expandido (consulta Usa clases de tamaño de ventana) en orientación horizontal. Las pantallas de ancho mediano o compacto admiten la visualización de las áreas principal y secundaria si el contenido se adapta a espacios de visualización más estrechos o si el contenido adicional se puede ocultar inicialmente en una hoja inferior o lateral a la que se puede acceder a través de un control, como un menú o un botón.

Un diseño de panel complementario difiere de un diseño de lista-detalles en la relación del contenido principal y secundario. El contenido del panel secundario es significativo solo en relación con el contenido principal. Por ejemplo, una ventana de herramientas del panel complementario es irrelevante por sí sola. Sin embargo, el contenido complementario del panel de detalles de un diseño de lista y detalles es significativo incluso sin el contenido principal. Por ejemplo, la descripción de un producto de una ficha de producto.

Estos son algunos casos de uso del panel complementario:

Figura 3: App de compras con descripciones de productos en un panel complementario.

Implementación

Compose 支持窗口大小类别逻辑,可用于确定是同时显示主要内容和辅助内容,还是将辅助内容放置在其他位置。

提升所有状态,包括当前窗口大小类别以及与主要内容和辅助内容中的数据相关的信息。

对于较小宽度的显示屏,可将辅助内容放置在主要内容下方或底部动作条中。对于中等宽度和较大宽度的显示屏,可将辅助内容放置在主要内容旁边,并根据内容和可用空间适当调整辅助内容的大小。对于中等宽度的显示屏,可在主要内容和辅助内容之间平均分配显示空间。对于展开宽度,可为主要内容分配 70% 的空间,并为辅助内容分配 30% 的空间。

SupportingPaneScaffold 是一种高级可组合项,可简化对辅助窗格布局的实现。该可组合函数会根据窗口大小类别自动处理窗格逻辑,在大屏幕上并排显示窗格,或在小屏幕上隐藏辅助窗格。SupportingPaneScaffold 还支持窗格之间的导航。

以下是最低限度的实现:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun MySupportingPaneScaffold() {
    // Creates and remembers a navigator to control pane visibility and navigation
    val navigator = rememberSupportingPaneScaffoldNavigator()
    SupportingPaneScaffold(
        // Directive and value help control pane visibility based on screen size and state
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        mainPane = {
            // Main Pane for the primary content
        },
        supportingPane = {
            //Supporting Pane for supplementary content
        }
    )
}
示例中的关键组件:

  • rememberSupportingPaneScaffoldNavigator:用于创建导航器以管理窗格可见性(例如,在紧凑型屏幕上隐藏或显示支持窗格)的可组合函数
  • mainPane:用于显示主要内容的可组合项
  • supportingPane:用于显示补充内容的可组合项

如需查看详细的实现示例,请参阅:

Recursos adicionales