Como adicionar cores dinâmicas ao app

1. Antes de começar

Neste codelab, você vai atualizar o app inicial, um app para calcular gorjetas, para usar os novos recursos do Material Design 3, permitindo que a interface do usuário tenha um tema dinâmico com base no plano de fundo do usuário. Veja abaixo algumas capturas de tela do aplicativo com cores dinâmicas aplicadas. Você também examinará alguns cenários adicionais que permitem controlar como as cores são aplicadas.

Pré-requisitos

Os desenvolvedores devem ser

  • Conhecer os conceitos básicos de aplicação de temas no Android
  • Confortável para modificar o tema de um app

O que você vai aprender

  • Como diferenciar os componentes já criados dos temas do Material 3
  • Como atualizar um tema para o Material 3
  • Como criar e aplicar temas usando nossas ferramentas
  • Como os atributos de tema se relacionam uns com os outros

O que é necessário

2. Visão geral do app inicial

O Tip Time é um app de calculadora de gorjetas com opções para personalizar esse valor. Ele é um dos apps de exemplo do nosso curso de treinamento Noções básicas do Android em Kotlin.

59906a9f19d6b804.png

3. Como atualizar dependências do Gradle

Antes de atualizarmos o tema real e aplicarmos a cor dinâmica, há algumas mudanças que precisam ser feitas no arquivo build.gradle do seu aplicativo.

Na seção de dependências, verifique se a biblioteca do Material Design é 1.5.0-alpha04 ou mais recente:

dependencies {
    // ...
    implementation 'com.google.android.material:material:<version>'
}

Na seção do Android, mude a compileSdkVersion e a targetSdkVersion.

para 31 ou posterior:

android {
    compileSdkVersion 31
    // ...

    defaultConfig {
        // ...
        targetSdkVersion 31
    }
}

Estas instruções pressupõem um app com dependências relativamente recentes. Para apps que ainda não usam o Material Design ou têm uma versão menos recente, consulte as instruções na documentação para começar (link em inglês) dos Componentes do Material Design para Android.

Sempre que você tiver criado seus temas, mude as referências de Theme.MaterialComponents.* para Theme.Material3.*. Alguns estilos ainda não têm um novo estilo no namespace do Material3, mas a maioria dos componentes ainda vai herdar o novo estilo quando o tema pai for atualizado para Theme.Material3.*. Veja abaixo que os botões agora assumem o novo tema arredondado.

No arquivo de temas abaixo, a única coisa que foi alterada foi o tema pai. Substituiremos totalmente esse tema em breve. Alguns dos atributos de cor foram descontinuados e alguns dos estilos personalizados que criamos agora são padrão no Material3, mas queríamos que você tivesse

themes.xml

<style name="Theme.TipTime" parent="Theme.Material3.Light">
   <!-- Primary brand color. -->
   <item name="colorPrimary">@color/green</item>
   <item name="colorPrimaryVariant">@color/green_dark</item>
   <item name="colorOnPrimary">@color/white</item>
   <!-- Secondary brand color. -->
   <item name="colorSecondary">@color/blue</item>
   <item name="colorSecondaryVariant">@color/blue_dark</item>
   <item name="colorOnSecondary">@color/black</item>
   <!-- Status bar color. -->
   <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
   <!-- For text input fields -->
   <item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
   <!-- For radio buttons -->
   <item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
   <!-- For switches -->
   <item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>

f91e2acbac7cd469.png

4. Noções básicas sobre temas de cores e funções de cores

O sistema de cores do Material 3 usa uma abordagem organizada para aplicar cores à interface. Vários atributos de Theme.AppCompat ainda estão em uso. No entanto, mais atributos foram adicionados em Theme.MaterialComponents.* e muito mais em Theme.Material3.*. Por isso, é importante examinar todas as telas do app para garantir que nenhuma propriedade não implementada esteja vazando o tema base.

Noções básicas sobre as funções de cor

Há mais de vinte atributos relacionados à cor em um tema do Material 3. Isso pode parecer complicado no início, mas existem algumas cores-chave que combinam com os mesmos quatro ou cinco papéis de cores para criar cores derivadas.

Esses grupos de cores são:

  • Primária, a cor primária do app
  • Secundária: a cor secundária do app.
  • Terciária, uma terceira cor complementar à primária e à secundária
  • Error, usado para texto de erro e caixas de diálogo
  • Contexto
  • Surface, SurfaceVariant, Surface inverse

Os papéis são os seguintes para Principal, Secundário, Terciário e Erro:

<cor de base>

A cor de base

em <cor de base>

a cor dos ícones e do texto que aparecem na cor de base

<cor de base>Contêiner

derivados da base, cor, usado para botões, caixas de diálogo, etc.

em <cor de base>Contêiner

a cor dos ícones e do texto do contêiner

Por exemplo, um botão de ação flutuante com estilo padrão no Material 3 usa Primary como cor de base e, portanto, usa primaryContainer para a cor de fundo do botão e onPrimaryContainer para o conteúdo.

Ao personalizar um tema manualmente, verifique no mínimo se o atributo on<base color> de cada cor de base que você mudar ainda está legível.

As práticas recomendadas são ajustar todos os papéis em um grupo de cores ao mesmo tempo, para garantir que não haja artefatos da base para o app.

As cores de base do plano de fundo e da superfície geralmente têm duas funções: para a cor de base em si e on<base color> para os ícones ou o texto que aparecem sobre ele.

5. Como criar um tema do Material 3 com o Material Theme Builder

O Material Theme Builder facilita a criação de um esquema de cores personalizado, o uso da exportação de código integrada para migrar para o sistema de cores M3 e aproveitar as cores dinâmicas. Saiba mais material.io/material-theme-builder

O tema do app Tip Time contém vários estilos para componentes. No entanto, a maioria dos estilos é padrão nos temas do Material 3. As únicas duas cores-chave com que precisamos nos preocupar são a primária e a secundária.

Elas correspondem a uma cor verde primária (#1B5E20) e uma cor secundária azul (#0288D1).

Você pode inserir essas cores no Material Theme Builder e exportar um tema completo (supondo que haja um link para uma visão geral completa em outro lugar).

Esteja ciente de que as cores inseridas podem mudar de tom para se adequar ao algoritmo de geração de cores e garantir cores complementares e legíveis.

Veja abaixo um subconjunto dos valores gerados quando você insere cores personalizadas.

7f6c5a33f5233811.png

6. Como trabalhar com arquivos de exportação do Material Theme Builder

O arquivo de exportação contém valores e diretórios values-night/ com seu próprio arquivo themes.xml, correspondente aos temas claro e escuro. Todas as cores são definidas em values/colors.xml.

f66a64db2989a260.png

Os arquivos podem ser copiados no estado em que se encontram, mas será necessário mudar o nome do tema como AndroidManifest.xml ou nos arquivos do tema para corresponder um ao outro. O nome padrão das ferramentas é AppTheme.

Reinicie o app e ele vai ficar quase igual. Uma mudança notável é a Switch e o RadioButtons, que agora têm estados selecionados com tons da cor primária em comparação com as cores secundárias. Em aplicativos maiores, talvez seja necessário revisar alguns designs.

38a50ada47fd5ea4.png

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.tiptime">

   <application ...>
       <activity android:name=".MainActivity"
           android:exported="true">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>

</manifest>

7. Como adicionar cores dinâmicas

Com um tema adequado do Material 3 em uso, podemos tornar a interface dinâmica com algumas pequenas adições.

A API Dynamic Colors permite aplicar cores dinâmicas a todas as atividades

em um app, atividades individuais ou visualizações ou fragmentos individuais. Para

neste app, aplicaremos cores dinâmicas globalmente.

Criar um arquivo da classe Application

class TipTimeApplication: Application() {
    override fun onCreate() {
        // Apply dynamic color
        DynamicColors.applyToActivitiesIfAvailable(this)
    }
}

Precisamos referenciar esse arquivo recém-criado no manifesto do Android:

AndroidManifest.xml

< application android name=".TipTimeApplication
<!--- Other existing attributes –>

</application >

Em sistemas Android 12 e versões mais recentes, o papel de parede do usuário para o esquema padrão) é examinado para gerar várias paletas de tons. Os valores dessas paletas são usados para criar um ThemeOverlay.

A classe DynamicColors registra um ActivityLifecycleCallbacks que intercepta em ActivityPreCreated para aplicar a sobreposição de tema dinâmico criada pelo sistema ou uma que você tenha fornecido.

eba71f96f4ba9cdf.png

8. Como aplicar uma sobreposição de tema personalizado

Nossas ferramentas podem exportar sobreposições de temas, mas você também pode criá-las manualmente se estiver substituindo um pequeno número de atributos.

Uma sobreposição de tema deve ser usada com outro tema e só fornece os valores que vão ser alterados sobre o tema base.

Vamos supor que, por algum motivo, talvez de branding, precisamos que os tons de cores primárias sejam tons de vermelho. Podemos fazer isso com os arquivos e atributos abaixo.

colors.xml

<resources>
    <color name="overlay_light_primary">#9C4146</color>
    <color name="overlay_light_onPrimary">#FFFFFF</color> 
    <color name= "overlay_light_primaryContainer">#FFDADB</color>
    <color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >

themes_overlays.xml

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
    <item name="colorPrimary">@color/overlay_light_primary</item>
    <item name="colorOnPrimary">@color/overlay_light_onPrimary</item> 
    <item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item> 
    <item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>

Para o código acima, o Android 12 vai aplicar um tema claro dinâmico e sobrepor as mudanças. Como alternativa, você pode usar qualquer ThemeOverlay válido como pai, incluindo qualquer um dos seguintes itens:

ThemeOverlay.Material3.Light

ThemeOverlay.Material3.Dark

ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark

ThemeOverlay.Material3.DynamicColors.DayNight

Para usar essa sobreposição de tema em vez do padrão do Material Design, mude a chamada para DynamicColors.applyToActivitiesIfAvailable para:

DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

d87020776782036f.png

9. Adicionar cores dinâmicas aos atributos personalizados

Até agora, substituímos as propriedades que já existem em um tema do Material 3. Há outro caso possível na cor dinâmica, em que podemos ter um ou mais atributos personalizados que precisam ser alocados.

Quando um app ativa as cores dinâmicas, ele tem acesso a cinco paletas tonais: três paletas de destaque e duas paletas neutras com os seguintes papéis aproximados:

system_accent1

Tons de cores primárias

system_accent2

Tons de cores secundárias

system_accent3

Tons de cores terciários

system_neutral1

Planos de fundo e superfícies neutros

system_neutral2

Superfícies e contornos neutros

Cada paleta possui uma série de etapas tonais que variam do branco

para preto: 0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000.

Ao projetar uma interface para cores dinâmicas, você precisa pensar menos na cor específica e mais na relação do tom e da luminância desse componente com outros no sistema de design.

Digamos que você queira definir um tema para os ícones usando a paleta de destaque secundária e adicionou um atributo para colorir os ícones com a entrada a seguir em attrs.xml.

attrs.xml

<resources>
    <attr name="iconColor" format="color" />
</resources>

A sobreposição do tema pode ficar assim:

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight"> 
<item name="iconColor">@android:color/system_accent2_600</item>
</style>

Quando você reinstalar o app e mudar o plano de fundo, ele vai usar essa paleta secundária.

11ef0035702640d9.png

264b2c2e74c5f574.png

Essas paletas são específicas do Android 12 (nível 31 da API), então é necessário colocar arquivos relevantes em pastas com o sufixo -v31, a menos que o app tenha um SDK mínimo definido como 31 ou mais recente.

10. Resumo

Neste codelab, você aprendeu a:

  • Adicione dependências para fazer upgrade do tema para o Material 3.
  • Entenda os novos grupos de cores e funções.
  • Entenda como migrar de um tema estático para uma cor dinâmica.
  • Saiba como usar sobreposições de tema e cores dinâmicas para atributos de tema personalizado.