Cómo personalizar las barras del sistema

Para personalizar las barras del sistema, usa una combinación de configuraciones XML y módulos Dagger para los componentes de la IU.

Cómo definir el comportamiento de la barra del sistema

Para definir una barra del sistema, usa la etiqueta <SystemBar> en un archivo en formato XML para definir la apariencia y la animación. Este archivo XML forma parte de una superposición de recursos en tiempo de ejecución (RRO).

Atributos de la etiqueta SystemBar

El elemento raíz para una configuración de barra del sistema es <SystemBar>, que admite estos atributos:

Atributo Estado Descripción
id Obligatorio Es el ID de recurso único para la barra del sistema. Por ejemplo:@id/my_custom_status_bar
type Obligatorio Especifica el tipo de barra del sistema, que puede ser status o navigation.
barZOrder Obligatorio

Es un número entero que representa el orden Z de la barra del sistema. Los valores más altos indican que el sistema dibuja la barra sobre otras. Debe ser un número entero positivo. Se aplican las siguientes reglas:

  • Si muestras una barra del sistema sobre una notificación emergente, este valor debe ser mayor que 10.
  • Las barras del sistema superpuestas no pueden tener el mismo orden Z
defaultVariant Obligatorio ID del objeto <Variant> que se aplica de forma predeterminada cuando se inicializa la barra del sistema
displayId Opcional ID del objeto <Variant> que se aplica de forma predeterminada cuando se inicializa la barra del sistema
hideForKeyboard Opcional

Valor booleano de true o false para indicar si la barra del sistema se oculta automáticamente cuando el teclado de software está activo. El valor predeterminado de este atributo es false.

Cuando este atributo es true, debes proporcionar transiciones de _System_Show_Panel y _System_Hide_Panel para la barra del sistema.

dragOpenNotification Opcional

Valor booleano de true o false para indicar si la barra del sistema activa automáticamente la apertura del panel de notificaciones. El valor predeterminado de este atributo es false.

dragCloseNotification Opcional

Valor booleano de true o false para indicar si la barra del sistema activa automáticamente el cierre del panel de notificaciones. El valor predeterminado de este atributo es false.

IDs y tipos de barras del sistema

Evita usar TopCarSystemBar, BottomCarSystemBar, LeftCarSystemBar y RightCarSystemBar como valores de id. El sistema reserva estos IDs para la compatibilidad con versiones anteriores, y su uso puede generar un comportamiento inesperado.

Para las configuraciones básicas de la barra de estado superior y la barra de navegación inferior, usa status y nav, respectivamente, como los valores del atributo type.

Si usas estos IDs, puedes omitir la sección titulada Proporciona una IU de barra del sistema con Dagger.

<Variant>
Define estados visuales. Para obtener más información, consulta Cómo usar una variante para diseñar un estado visual. En la etiqueta <SystemBar>, define una o más etiquetas <Variant>. Cada variante representa un estado visual distinto y contiene propiedades que controlan la apariencia de la barra del sistema en ese estado.
<Visibility isVisible="true|false">
Controla la visibilidad de la barra del sistema. El booleano isVisible indica si la barra del sistema está visible o no.
<Alpha alpha="float_value">
Controla la transparencia de la barra del sistema. El valor de alpha varía entre 0.0 (completamente transparente) y 1.0 (completamente opaco).
<Bounds .../>

Define la posición y el tamaño de la barra del sistema. En el caso de los elementos <SystemBar>, los límites deben tocar al menos un borde de la pantalla (izquierdo, superior, derecho o inferior). Los atributos son los siguientes:

  • left, top, right, bottom: Coordenadas absolutas.
  • width, height: Dimensiones.
  • leftOffset, topOffset, rightOffset, bottomOffset: Desplazamientos hacia el centro del rectángulo.
<Corner radius="dimen"/>

Define el radio de esquina de la barra del sistema. Para radius, ingresa la dimensión del radio de la esquina.

<Insets .../>

Define las inserciones de la barra del sistema. Los atributos son left, top, right y bottom. Para cada atributo, ingresa un valor de dimensión para las inserciones.

<Gravity .../>

Define la gravedad del contenido de la barra del sistema. Para obtener más información, consulta HunTagXmlParserKt.GRAVITY_TAG en el código fuente.

  • Cuando omites un valor para la gravedad, el sistema lo calcula de forma interna.
  • Los valores admitidos son combinaciones de TOP, BOTTOM, LEFT, RIGHT, CENTER, CENTER_HORIZONTAL, CENTER_VERTICAL y FILL_HORIZONTAL, cada uno separado por un carácter |.

Unidades de dimensión

Especifica dimensiones con px, dp (o dip), % o referencias a recursos dimension, integer, fraction, string o attribute.

Transiciones: Cómo animar entre variantes

Para obtener más información, consulta Cómo configurar una transición. Usa el bloque <Transitions> para definir cómo se anima la barra del sistema entre diferentes variantes:

Elemento Atributo de etiqueta
<Transition> fromVariant, toVariant, onEvent, onEventTokens, animator, duration, delay, interpolator
<Transitions> defaultDuration, defaultInterpolator

La IU escalable admite transiciones en las barras del sistema solo cuando las defines para casos de uso en modo no inmersivo. Esto significa que el modo envolvente no activa transiciones de renderización en ventanas de IU escalable para las barras del sistema cuando oculta (o muestra) una barra del sistema.

La IU adaptable sigue enviando eventos para ocultar (o mostrar) una barra del sistema, de modo que otros paneles puedan responder según sea necesario, mientras que las transiciones para ocultar y mostrar barras del sistema deben proporcionarse para el funcionamiento adecuado del atributo hideForKeyboard. Considera esta estructura XML de muestra:

<SystemBar id="@id/my_custom_status_bar" type="status" barZOrder="0" defaultVariant="@id/default_variant" hideForKeyboard="true">
    <Variant id="@+id/default_variant">
        <Bounds top="0px" left="0px" right="100%" height="100px"/>
        <Visibility isVisible="true"/>
    </Variant>
    <Variant id="@+id/hidden_variant" parent="@id/default_variant">
        <Visibility isVisible="false"/>
    </Variant>
    <Transitions>
        <Transition onEvent="_System_Show_Panel" onEventTokens="panelId= my_custom_status_bar" toVariant="@id/default_variant"/>
        <Transition onEvent="_System_Hide_Panel" onEventTokens="panelId= my_custom_status_bar" toVariant="@id/hidden_variant"/>
    </Transitions>
</SystemBar>

Proporciona una IU de barra del sistema con Dagger

Después de definir la barra del sistema en XML, proporciona los View y Window reales. Para ello, aplica una anulación de la aplicación al módulo predeterminado de Dagger, CarSystemBarModule.java. Por ejemplo:

import com.android.systemui.car.systembar.CarSystemBarViewSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplierUsingLayout;
import com.example.R;

import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;

@Module
public abstract class MySystemBarModule extends CarSystemBarModule {

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarViewSupplier bindMyCustomStatusBarViewSupplier() {
        return new CarSystemBarViewSupplierUsingLayout(
            R.layout.my_custom_status_bar, // provisioned layout
            R.layout.my_custom_status_bar_unprovisioned // unprovisioned layout
        );
    }

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarWindowSupplier bindMyCustomStatusBarWindowSupplier() {
        return new CarSystemBarWindowSupplierUsingLayout(
            R.layout.my_navigation_bar_window, // Can reuse existing window layouts
            R.id.my_custom_bar_window // The ID that will be assigned to the window
        );
    }
}

Cómo crear un módulo de Dagger en una anulación de SystemUI

Para inflar tus recursos de diseño personalizados, usa las clases CarSystemBarViewSupplierUsingLayout y CarSystemBarWindowSupplierUsingLayout.

Crea un módulo de Dagger para proporcionar tus proveedores personalizados. El @StringKey debe coincidir con el id de la etiqueta XML <SystemBar>.

Para anular CarSystemBarModule, consulta esta muestra de código:

import com.android.systemui.car.systembar.CarSystemBarViewSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplier;
import com.android.systemui.car.systembar.CarSystemBarWindowSupplierUsingLayout;
import com.example.R;

import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;

@Module
public abstract class MySystemBarModule extends CarSystemBarModule {

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarViewSupplier bindMyCustomStatusBarViewSupplier() {
        return new CarSystemBarViewSupplierUsingLayout(
            R.layout.my_custom_status_bar, // provisioned layout
            R.layout.my_custom_status_bar_unprovisioned // unprovisioned layout
        );
    }

    @Provides
    @IntoMap
    @StringKey("my_custom_status_bar") // Matches the <SystemBar> id
    static CarSystemBarWindowSupplier bindMyCustomStatusBarWindowSupplier() {
        return new CarSystemBarWindowSupplierUsingLayout(
            R.layout.my_navigation_bar_window, // Can reuse existing window layouts
            R.id.my_custom_bar_window // The ID that will be assigned to the window
        );
    }
}

Usa un RRO para crear una configuración a nivel del sistema

Establece varias configuraciones a nivel del sistema que afectan las barras del sistema en el archivo res/values/config.xml de tu RRO.

Inhabilita las barras del sistema heredadas

Para evitar conflictos con la IU escalable, inhabilita las configuraciones heredadas de la barra del sistema estableciendo las siguientes marcas en false:

<resources>
    <bool name="config_enableTopSystemBar">false</bool>
    <bool name="config_enableBottomSystemBar">false</bool>
    <bool name="config_enableLeftSystemBar">false</bool>
    <bool name="config_enableRightSystemBar">false</bool>
</resources>

Ubicación del indicador de privacidad

El recurso de cadena config_privacyIndicatorLocation especifica qué barra del sistema aloja los indicadores de privacidad. El valor debe ser el nombre id de un <SystemBar>.

<resources>
    <!-- "my_custom_status_bar" corresponds to the android:id name of a SystemBar -->
    <string name="config_privacyIndicatorLocation">my_custom_status_bar</string>
</resources>

Objetos de escucha de eventos de arrastre

Estas configuraciones especifican qué barras del sistema detectan eventos de arrastre (por ejemplo, para deslizar el dedo hacia abajo y abrir el panel de notificaciones). A partir del SO Android Automotive con IU escalable, usa atributos XML como opción predeterminada en lugar de arrays de recursos de detección controlada para definir estas capacidades.

Recomendado: Descubrimiento basado en XML (IU escalable)

Usa los atributos dragOpenNotification y dragCloseNotification directamente en la etiqueta <SystemBar> dentro del XML de la superposición:

<SystemBar id="@id/my_custom_status_bar" type="status" barZOrder="0" defaultVariant="@id/default_variant" dragOpenNotification="true">
    <Variant id="@+id/default_variant">
        <Bounds top="0px" left="0px" right="100%" height="100px"/>
        <Visibility isVisible="true"/>
    </Variant>
</SystemBar>

Heredado: Array de recursos (copia de seguridad)

Si mantienes una compilación de IU no escalable o necesitas especificar listeners para dispositivos compatibles con versiones anteriores, usa el enfoque heredado string-array en res/values/config.xml en tu RRO. Estos recursos string-array especifican qué barras del sistema detectan eventos de arrastre. Por ejemplo, para abrir el panel de notificaciones. Cada <item> es el nombre de id de una barra del sistema.

  • config_registerHvacDragCloseListener
  • config_notificationDragOpenListener
  • config_notificationDragCloseListener

Por ejemplo:

<resources>
    <string-array name="config_notificationDragOpenListener" translatable="false">
        <item>my_custom_status_bar</item>
    </string-array>
</resources>

Compila e implementa

Para compilar e implementar una barra de estado, haz lo siguiente:

  1. Escribe en la memoria flash del dispositivo con la aplicación de anulación de SystemUI modificada.

  2. Usa el sistema de compilación de Android (m) para compilar tu proyecto de RRO.

  3. Implementa el APK del RRO generado en tu dispositivo Android Automotive. Usa adb install o escribe en la memoria flash una compilación completa que incluya tu RRO.