Personalizar barras de sistema

Para personalizar as barras de sistema, use uma combinação de configurações XML e módulos Dagger nos componentes da interface.

Definir o comportamento da barra de sistema

Para definir uma barra de sistema, use a tag <SystemBar> em um arquivo XML para definir a aparência e a animação. Esse arquivo XML faz parte de uma sobreposição de recursos no momento da execução (RRO, na sigla em inglês).

Atributos da tag SystemBar

O elemento raiz de uma configuração de barra de sistema é <SystemBar>, que oferece suporte a estes atributos:

Atributo Status Descrição
id Obrigatório ID de recurso exclusivo da barra de sistema. Por exemplo, @id/my_custom_status_bar
type Obrigatório Especifica o tipo de barra de sistema, que é status ou navigation
barZOrder Obrigatório

Número inteiro para representar a ordem Z da barra de sistema. Valores mais altos indicam que o sistema desenha a barra acima de outras. Precisa ser um número inteiro positivo. Estas regras se aplicam:

  • Se você mostrar uma barra de sistema acima de uma notificação pop-up, então esse valor precisará ser maior que 10
  • As barras de sistema sobrepostas não podem ter a mesma ordem Z
defaultVariant Obrigatório ID do <Variant> que é aplicada por padrão quando a barra de sistema é inicializada
displayId Opcional ID do <Variant> que é aplicada por padrão quando a barra de sistema é inicializada
hideForKeyboard Opcional

Valor booleano de true ou false para indicar se a barra de sistema é ocultada automaticamente quando o teclado de software está ativo. Esse atributo é definido como false por padrão.

Quando esse atributo é true, você precisa fornecer _System_Show_Panel e _System_Hide_Panel transições para a barra de sistema.

dragOpenNotification Opcional

Valor booleano de true ou false para indicar se a barra de sistema aciona automaticamente a abertura do painel de notificações. Esse atributo é definido como false por padrão.

dragCloseNotification Opcional

Valor booleano de true ou false para indicar se a barra de sistema aciona automaticamente o fechamento do painel de notificações. Esse atributo é definido como false por padrão.

IDs e tipos de barra de sistema

Evite usar TopCarSystemBar, BottomCarSystemBar, LeftCarSystemBar e RightCarSystemBar como valores id. O sistema reserva esses IDs para compatibilidade com versões anteriores, e o uso deles pode levar a um comportamento inesperado.

Para configurações básicas de barra de status superior e barra de navegação inferior, use status e nav, respectivamente, como os valores do atributo type.

Se você usar esses IDs, poderá pular a seção intitulada Fornecer uma interface de barra de sistema com o Dagger.

<Variant>
Define estados visuais. Para saber mais, consulte Usar uma variante para projetar um estado visual. Na tag <SystemBar>, defina uma ou mais <Variant> tags. Cada variante representa um estado visual distinto e contém propriedades que controlam a aparência da barra de sistema nesse estado.
<Visibility isVisible="true|false">
Controla a visibilidade da barra de sistema. O booleano isVisible sinaliza se a barra de sistema está visível ou não.
<Alpha alpha="float_value">
Controla a transparência da barra de sistema. O valor de alpha flutua entre 0.0 (totalmente transparente) e 1.0 (totalmente opaco).
<Bounds .../>

Define a posição e o tamanho da barra de sistema. Para elementos <SystemBar>, os limites precisam tocar pelo menos uma borda da tela (esquerda, superior, direita ou inferior). Os atributos são:

  • left, top, right, bottom: coordenadas absolutas.
  • width, height: dimensões.
  • leftOffset, topOffset, rightOffset, bottomOffset: deslocamentos em direção ao centro do retângulo.
<Corner radius="dimen"/>

Define o raio do canto da barra de sistema. Para radius, insira a dimensão do raio do canto.

<Insets .../>

Define recuos para a barra de sistema. Os atributos são left, top, right e bottom. Para cada atributo, insira um valor de dimensão para os recuos.

<Gravity .../>

Define a gravidade do conteúdo da barra de sistema. Para saber mais, consulte HunTagXmlParserKt.GRAVITY_TAG no código-fonte.

  • Quando você omite um valor de gravidade, o sistema o calcula internamente.
  • Os valores aceitos são combinações de TOP, BOTTOM, LEFT, RIGHT, CENTER, CENTER_HORIZONTAL, CENTER_VERTICAL, e FILL_HORIZONTAL, cada um separado por um caractere |.

Unidades de dimensão

Especifique dimensões com px, dp (ou dip), % ou referências a recursos dimension, integer, fraction, string ou attribute.

Transições: animar entre variantes

Para saber mais, consulte Configurar uma transição. Use o bloco <Transitions> para definir como a barra de sistema é animada entre diferentes variantes:

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

A interface escalonável oferece suporte a transições em barras de sistema somente quando você as define para casos de uso no modo não imersivo. Isso significa que o modo imersivo não aciona transições de janelas da interface escalonável para barras de sistema quando oculta (ou mostra) uma barra de sistema.

A interface escalonável continua enviando eventos para ocultar (ou mostrar) uma barra de sistema para que outros painéis possam responder conforme necessário, enquanto as transições para ocultar e mostrar barras de sistema precisam ser fornecidas para o funcionamento adequado do atributo hideForKeyboard. Considere este exemplo de estrutura XML:

<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>

Fornecer uma interface de barra de sistema com o Dagger

Depois de definir a barra de sistema em XML, forneça a View e a Window reais. Para fazer isso, aplique uma substituição de aplicativo ao módulo Dagger padrão, CarSystemBarModule.java. Exemplo:

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

Criar um módulo Dagger em uma substituição do SystemUI

Para inflar seus recursos de layout personalizados, use as classes CarSystemBarViewSupplierUsingLayout e CarSystemBarWindowSupplierUsingLayout.

Crie um módulo Dagger para fornecer seus fornecedores personalizados. O @StringKey precisa corresponder ao id na tag XML <SystemBar>.

Para substituir CarSystemBarModule, consulte este exemplo 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
        );
    }
}

Usar uma RRO para criar uma configuração no nível do sistema

Defina várias configurações no nível do sistema que afetam as barras de sistema no arquivo res/values/config.xml na sua RRO.

Desativar barras de sistema legadas

Para evitar conflitos com a interface escalonável, desative as configurações legadas da barra de sistema definindo as seguintes flags como 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>

Local do indicador de privacidade

O recurso de string config_privacyIndicatorLocation especifica qual barra de sistema hospeda indicadores de privacidade. O valor precisa ser o id nome de um <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>

Listeners de eventos de arrastar

Essas configurações especificam quais barras de sistema ficam atentas a eventos de arrastar (por exemplo, para deslizar para baixo e abrir o painel de notificações). A partir do Android Automotive OS com a interface escalonável, use atributos XML como padrão em vez de matrizes de recursos de descoberta orientada para definir esses recursos.

Recomendado: descoberta orientada por XML (interface escalonável)

Use os atributos dragOpenNotification e dragCloseNotification diretamente na tag <SystemBar> dentro do XML de sobreposição:

<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>

Legado: matriz de recursos (fallback)

Se você estiver mantendo uma build de interface não escalonável ou precisar especificar listeners para dispositivos compatíveis com versões anteriores, use a abordagem legada string-array em res/values/config.xml na sua RRO. Esses recursos string-array especificam quais barras de sistema ficam atentas a eventos de arrastar. Por exemplo, para abrir o painel de notificações. Cada <item> é o nome id de uma barra de sistema.

  • config_registerHvacDragCloseListener
  • config_notificationDragOpenListener
  • config_notificationDragCloseListener

Exemplo:

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

Criar e implantar

Para criar e implantar uma barra de status:

  1. Atualize o dispositivo com o aplicativo de substituição do SystemUI modificado.

  2. Use o sistema de build do Android (m) para compilar seu projeto de RRO.

  3. Implante o APK de RRO gerado no seu dispositivo Android Automotive. Use adb install ou atualize uma build completa que inclua sua RRO.