Estilos e temas

Experimente trabalhar com o Compose
O Jetpack Compose é o kit de ferramentas de IU recomendado para Android. Saiba como trabalhar com temas no Compose.

Os estilos e temas no Android permitem separar os detalhes do design do app da estrutura e do comportamento da interface, de forma semelhante às folhas de estilo no web design.

Um estilo é uma coleção de atributos que especifica a aparência de uma única View. Um estilo pode especificar atributos, como cor e tamanho da fonte, cor do plano de fundo e muito mais.

Um tema é uma coleção de atributos aplicada a um app, uma atividade ou uma hierarquia de visualização inteira, não apenas a uma visualização individual. Quando você aplica um tema, cada visualização no app ou na atividade aplica cada um dos atributos do tema que ela aceita. Os temas também podem aplicar estilos a elementos que não são de visualização, como a barra de status e o plano de fundo da janela.

Os estilos e temas são declarados em um arquivo de recurso de estilo em res/values/, geralmente chamado de styles.xml.

Figura 1. Dois temas aplicados à mesma atividade: Theme.AppCompat (à esquerda) e Theme.AppCompat.Light (à direita).

Temas x estilos

Os temas e estilos têm muitas semelhanças, mas são usados para finalidades diferentes. Temas e estilos têm a mesma estrutura básica: um par de chave-valor que mapeia atributos para recursos.

O estilo especifica atributos para um determinado tipo de visualização. Por exemplo, um estilo pode especificar os atributos de um botão. Cada atributo especificado em um estilo pode ser definido no arquivo de layout. Extrair todos os atributos para um estilo facilita o uso e a manutenção deles em vários widgets.

Um tema define uma coleção de recursos nomeados que podem ser referenciados por estilos, layouts, widgets e assim por diante. Os temas atribuem nomes semânticos, como colorPrimary, aos recursos do Android.

Os estilos e temas devem ser usados em conjunto. Por exemplo, você pode ter um estilo que especifica que uma parte de um botão é colorPrimary e outra parte é colorSecondary. As definições reais dessas cores são fornecidas no tema. Quando o dispositivo entra no modo noturno, o app pode mudar do tema "claro" para o "escuro", alterando os valores de todos esses nomes de recursos. Não é necessário mudar os estilos, já que eles usam os nomes semânticos, e não definições de cores específicas.

Para mais informações sobre como temas e estilos funcionam juntos, consulte a postagem do blog Estilo do Android: temas x estilos (link em inglês).

Criar e aplicar um estilo

Para criar um novo estilo, abra o arquivo res/values/styles.xml do projeto. Para cada estilo que você quer criar, siga estas etapas:

  1. Adicione um elemento <style> com um nome que identifique o estilo de forma exclusiva.
  2. Adicione um elemento <item> para cada atributo de estilo que você quer definir. O name em cada item especifica um atributo que você usaria como um atributo XML no seu layout. O valor no elemento <item> é o valor desse atributo.

Por exemplo, suponha que você defina o seguinte estilo:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="GreenText" parent="TextAppearance.AppCompat">
        <item name="android:textColor">#00FF00</item>
    </style>
</resources>

Será possível aplicar o estilo a uma visualização da seguinte maneira:

<TextView
    style="@style/GreenText"
    ... />

Cada atributo especificado no estilo é aplicado à visualização, se ela o aceitar. A visualização ignora todos os atributos que não aceita.

No entanto, em vez de aplicar um estilo a visualizações individuais, geralmente os estilos são aplicados como um tema para todo o app, atividade ou coleção de visualizações, conforme descrito em outra seção deste guia.

Estender e personalizar um estilo

Ao criar seus próprios estilos, sempre estenda um estilo do framework ou da biblioteca de suporte para manter a compatibilidade com os estilos de IU da plataforma. Para estender um estilo, especifique o estilo que você quer estender com o atributo parent. Em seguida, é possível substituir os atributos de estilo herdados e adicionar novos.

Por exemplo, é possível herdar a aparência de texto padrão da plataforma Android e modificá-la da seguinte maneira:

<style name="GreenText" parent="@android:style/TextAppearance">
    <item name="android:textColor">#00FF00</item>
</style>

No entanto, sempre herde os estilos principais do app da Biblioteca de Suporte do Android. Os estilos na Biblioteca de Suporte oferecem compatibilidade otimizando cada estilo para os atributos de IU disponíveis em cada versão. Os estilos da Biblioteca de Suporte geralmente têm um nome semelhante ao estilo da plataforma, mas com AppCompat incluído.

Para herdar estilos de uma biblioteca ou do seu próprio projeto, declare o nome do estilo pai sem a parte @android:style/ mostrada no exemplo anterior. Por exemplo, o exemplo a seguir herda estilos de aparência de texto da biblioteca de suporte:

<style name="GreenText" parent="TextAppearance.AppCompat">
    <item name="android:textColor">#00FF00</item>
</style>

Também é possível herdar estilos, exceto os da plataforma, estendendo o nome de um estilo com uma notação de ponto, em vez de usar o atributo parent. Ou seja, adicione o nome do estilo que você quer herdar como prefixo ao nome do seu estilo, separados por um ponto. Normalmente, isso só é feito ao estender seus próprios estilos, não os de outras bibliotecas. Por exemplo, o estilo a seguir herda todos os estilos do GreenText no exemplo anterior e aumenta o tamanho do texto:

<style name="GreenText.Large">
    <item name="android:textSize">22dp</item>
</style>

Você pode continuar herdando estilos dessa forma quantas vezes quiser, encadeando mais nomes.

Para saber quais atributos podem ser declarados com uma tag <item>, consulte a tabela "Atributos XML" nas várias referências de classe. Todas as visualizações são compatíveis com atributos XML da classe de base View, e muitas visualizações adicionam os próprios atributos especiais. Por exemplo, os atributos XML TextView incluem o atributo android:inputType, que pode ser aplicado a uma visualização de texto que recebe entrada, como um widget EditText.

Aplicar um estilo como tema

Você pode criar um tema da mesma forma que cria estilos. A diferença é como você o aplica: em vez de aplicar um estilo com o atributo style em uma visualização, você aplica um tema com o atributo android:theme na tag <application> ou em uma tag <activity> no arquivo AndroidManifest.xml.

Por exemplo, veja como aplicar o tema "escuro" do Material Design da Biblioteca de Suporte do Android a todo o app:

<manifest ... >
    <application android:theme="@style/Theme.AppCompat" ... >
    </application>
</manifest>

Veja como aplicar o tema claro a apenas uma atividade:

<manifest ... >
    <application ... >
        <activity android:theme="@style/Theme.AppCompat.Light" ... >
        </activity>
    </application>
</manifest>

Cada visualização no app ou na atividade aplica os estilos compatíveis definidos no tema em questão. Se uma visualização for compatível com apenas alguns dos atributos declarados no estilo, ela vai aplicar somente esses atributos e ignorar os que não são compatíveis.

No Android 5.0 (nível 21 da API) e na Biblioteca de Suporte do Android v22.1, também é possível especificar o atributo android:theme para uma visualização no arquivo de layout. Isso modifica o tema dessa visualização e de todas as visualizações filhas, o que é útil para alterar as paletas de cores do tema em uma parte específica da interface.

Os exemplos anteriores mostram como aplicar um tema, como Theme.AppCompat, fornecido pela Biblioteca de Suporte do Android. No entanto, geralmente é necessário personalizar o tema para que ele se ajuste à marca do app. A melhor maneira de fazer isso é estender esses estilos da Biblioteca de Suporte e substituir alguns dos atributos, conforme descrito na seção a seguir.

Hierarquia de estilo

O Android oferece várias maneiras de definir atributos em todo o app Android. Por exemplo, é possível definir atributos diretamente em um layout, aplicar um estilo a uma visualização, aplicar um tema a um layout e até mesmo definir atributos de forma programática.

Ao escolher como definir o estilo do seu app, lembre-se da hierarquia de estilo do Android. Em geral, use temas e estilos o máximo possível para manter a consistência. Se você especificar os mesmos atributos em vários lugares, a lista a seguir vai determinar quais atributos serão aplicados. A lista é ordenada da precedência mais alta para a mais baixa.

  1. Aplicar estilo no nível de caractere ou parágrafo usando períodos de texto a classes derivadas de TextView.
  2. Aplicar atributos de forma programática.
  3. Aplicar atributos individuais diretamente a uma visualização.
  4. Como aplicar um estilo a uma visualização.
  5. Estilo padrão.
  6. Aplicar um tema a uma coleção de visualizações, uma atividade ou todo o app.
  7. Aplicar determinados estilos específicos de visualização, como definir um TextAppearance em um TextView.

Figura 2. O estilo de um span modifica o estilo de uma textAppearance.

TextAppearance

Uma limitação dos estilos é que somente um estilo pode ser aplicado a uma View. No entanto, em um TextView, também é possível especificar um atributo TextAppearance que funciona de maneira semelhante a um estilo, como mostrado no exemplo a seguir:

<TextView
    ...
    android:textAppearance="@android:style/TextAppearance.Material.Headline"
    android:text="This text is styled via textAppearance!" />

O TextAppearance permite definir um estilo específico de texto, deixando o estilo de um View disponível para outros usos. No entanto, se você definir atributos de texto diretamente no View ou em um estilo, esses valores vão substituir os valores de TextAppearance.

O TextAppearance é compatível com um subconjunto de atributos de estilo oferecidos pelo TextView. Para ver a lista completa de atributos, consulte TextAppearance.

Alguns atributos TextView comuns não incluídos são lineHeight[Multiplier|Extra], lines, breakStrategy e hyphenationFrequency. TextAppearance funciona no nível do caractere, não do parágrafo. Portanto, não há suporte para atributos que afetam todo o layout.

Personalizar o tema padrão

Quando você cria um projeto com o Android Studio, ele aplica um tema do Material Design ao app por padrão, conforme definido no arquivo styles.xml do projeto. Esse estilo AppTheme estende um tema da Biblioteca de Suporte e inclui substituições para atributos de cor usados por elementos importantes da interface, como a barra de apps e o botão de ação flutuante, se usado. Assim, você pode personalizar rapidamente o design de cores do app atualizando as cores fornecidas.

Por exemplo, o arquivo styles.xml é semelhante a este:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Os valores de estilo são, na verdade, referências a outros recursos de cor, definidos no arquivo res/values/colors.xml do projeto. Esse é o arquivo que você edita para mudar as cores. Consulte a Visão geral de cores do Material Design para melhorar a experiência do usuário com cores dinâmicas e outras cores personalizadas.

Com as cores definidas, atualize os valores em res/values/colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--   Color for the app bar and other primary UI elements. -->
    <color name="colorPrimary">#3F51B5</color>

    <!--   A darker variant of the primary color, used for
           the status bar (on Android 5.0+) and contextual app bars. -->
    <color name="colorPrimaryDark">#303F9F</color>

    <!--   a secondary color for controls like checkboxes and text fields. -->
    <color name="colorAccent">#FF4081</color>
</resources>

Em seguida, você pode substituir os outros estilos que quiser. Por exemplo, é possível mudar a cor de fundo da atividade da seguinte maneira:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:windowBackground">@color/activityBackground</item>
</style>

Para ver uma lista de atributos que podem ser usados no seu tema, consulte a tabela de atributos em R.styleable.Theme. Ao adicionar estilos para as visualizações no layout, você também pode encontrar atributos na tabela "Atributos XML" nas referências de classe de visualização. Por exemplo, todas as visualizações são compatíveis com atributos XML da classe base View.

A maior parte dos atributos é aplicada a tipos específicos de visualizações, e alguns são aplicados a todas elas. No entanto, alguns atributos de tema listados em R.styleable.Theme se aplicam à janela de atividade, não às visualizações no layout. Por exemplo, windowBackground muda o plano de fundo da janela, e windowEnterTransition define uma animação de transição para usar quando a atividade é iniciada. Para mais detalhes, consulte Iniciar uma atividade usando uma animação.

A Biblioteca de Suporte do Android também oferece outros atributos que podem ser usados para personalizar o tema estendido de Theme.AppCompat, como o atributo colorPrimary mostrado no exemplo anterior. Para conferir, acesse o arquivo attrs.xml da biblioteca.

Também há diferentes temas disponíveis na Biblioteca de Suporte que você pode estender, em vez dos mostrados no exemplo anterior. O melhor lugar para ver os temas disponíveis é o arquivo themes.xml da biblioteca.

Adicionar estilos específicos da versão

Se uma nova versão do Android adicionar atributos de temas que você quer usar, será possível adicioná-los ao seu tema e manter a compatibilidade com versões antigas. Basta salvar outro arquivo styles.xml em um diretório values que inclua o qualificador de versão do recurso:

res/values/styles.xml        # themes for all versions
res/values-v21/styles.xml    # themes for API level 21+ only

Como os estilos no arquivo values/styles.xml estão disponíveis para todas as versões, os temas em values-v21/styles.xml podem herdá-los. Isso significa que você pode evitar a duplicação de estilos começando com um tema "base" e, em seguida, estendendo-o nos estilos específicos da versão.

Por exemplo, para declarar transições de janela para o Android 5.0 (nível 21 da API) e versões mais recentes, é necessário usar novos atributos. Portanto, seu tema base em res/values/styles.xml pode ser assim:

<resources>
    <!-- Base set of styles that apply to all versions. -->
    <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/primaryTextColor</item>
        <item name="colorAccent">@color/secondaryColor</item>
    </style>

    <!-- Declare the theme name that's actually applied in the manifest file. -->
    <style name="AppTheme" parent="BaseAppTheme" />
</resources>

Em seguida, adicione os estilos específicos da versão em res/values-v21/styles.xml, da seguinte maneira:

<resources>
    <!-- extend the base theme to add styles available only with API level 21+ -->
    <style name="AppTheme" parent="BaseAppTheme">
        <item name="android:windowActivityTransitions">true</item>
        <item name="android:windowEnterTransition">@android:transition/slide_right</item>
        <item name="android:windowExitTransition">@android:transition/slide_left</item>
    </style>
</resources>

Agora, você pode aplicar AppTheme no arquivo de manifesto, e o sistema vai selecionar os estilos disponíveis para cada versão do sistema.

Para mais informações sobre o uso de recursos alternativos para diferentes dispositivos, consulte Como fornecer recursos alternativos.

Personalizar estilos de widgets

Cada widget no framework e na biblioteca de suporte tem um estilo padrão. Por exemplo, quando você estiliza o app usando um tema da Biblioteca de Suporte, uma instância de Button é estilizada usando o estilo Widget.AppCompat.Button. Se você quiser aplicar um estilo de widget diferente a um botão, use o atributo style no arquivo de layout. Por exemplo, o código abaixo aplica o estilo de botão sem borda da biblioteca:

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    ... />

Se você quiser aplicar esse estilo a todos os botões, declare-o no buttonStyle do tema da seguinte forma:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item>
    ...
</style>

Também é possível estender os estilos de widget, assim como qualquer outro estilo, e aplicar o estilo personalizado ao layout ou tema.

Outros recursos

Para saber mais sobre temas e estilos, consulte os seguintes recursos:

Postagens do blog