Capítulo 05: Material Design 3, Temas Dinâmicos (Monet), Tipografia e Shapes
Capítulo 05: Material Design 3, Temas Dinâmicos (Monet), Tipografia e Shapes
Especialização em Mobile Nativo com Android • Kotlin 2.0 & Jetpack Compose
🗺️ Mapa Conceitual do Design System Material 3 (M3)
flowchart TD
SOURCE["Origem Cromática (Wallpaper do Usuário ou Paleta de Marca)"] --> MONET["Algoritmo de Extração de Paleta Dinâmica (Monet)"]
subgraph TOKENS["Geração Automática de Tokens de Cor M3"]
MONET --> PRIMARY["Primary / OnPrimary / PrimaryContainer"]
MONET --> SECONDARY["Secondary / OnSecondary / SecondaryContainer"]
MONET --> TERTIARY["Tertiary / OnTertiary (Harmonização Externa)"]
MONET --> SURFACE["Surface / OnSurface / SurfaceVariant"]
MONET --> ERROR["Error / OnError / ErrorContainer"]
end
subgraph THEME["Provedor de Tema Compose (MaterialTheme)"]
PRIMARY --> COLOR_SCHEME["ColorScheme (lightColorScheme / darkColorScheme)"]
SURFACE --> COLOR_SCHEME
TYPO["Typography (Display, Headline, Title, Body, Label)"]
SHAPES["Shapes (ExtraSmall, Small, Medium, Large, ExtraLarge)"]
COLOR_SCHEME --> M3_THEME["MaterialTheme { ... }"]
TYPO --> M3_THEME
SHAPES --> M3_THEME
end
M3_THEME -->|"Injetado via CompositionLocal"| UI_COMPONENTS["Scaffold / Card / Button / NavigationBar"]
style SOURCE fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px
style MONET fill:#b3e5fc,stroke:#0288d1,stroke-width:2px
style COLOR_SCHEME fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style M3_THEME fill:#ede7f6,stroke:#7e57c2,stroke-width:2px
style UI_COMPONENTS fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
🏛️ 1. O Design System Material You e a Arquitetura M3
O Material Design 3 (M3), também conhecido como Material You, representa uma revolução de personalização e acessibilidade no ecossistema Android. Diferente do Material 2, que impunha paletas estáticas e rígidas, o M3 introduz o conceito de co-criação com o usuário:
- Dynamic Color (Monet Engine): A partir do Android 12 (API 31), o sistema operacional analisa as cores predominantes do papel de parede do usuário e gera dinamicamente 5 paletas tonais com 13 tons cromáticos calculados. O Jetpack Compose acessa esse motor nativo através das funções
dynamicLightColorScheme(context)edynamicDarkColorScheme(context). - Sistema Tonal de Contraste e Acessibilidade: No M3, as relações de cores são construídas com pares canônicos como
primaryeonPrimaryousurfaceContainereonSurface. Isso assegura que o contraste mínimo exigido pelas diretrizes WCAG (Web Content Accessibility Guidelines) seja matematicamente garantido em qualquer combinação dinâmica. - Escala Tipográfica Hierárquica: A tipografia M3 é estruturada em 15 papéis tipográficos semânticos divididos em 5 categorias principais:
Display,Headline,Title,BodyeLabel— cada um com variantesLarge,MediumeSmall.
📊 2. Comparativo Arquitetural: Material 2 vs Material 3 (Compose)
| Dimensão Visual & Técnica | Material Design 2 (M2) | Material Design 3 (M3 / Material You) | Benefício de Adoção |
|---|---|---|---|
| Cores Dinâmicas | Inexistente (Cores estáticas de marca no tema) | Suporte nativo a dynamicColorScheme via Monet Engine |
O app se integra harmonicamente ao gosto visual do usuário |
| Pares de Contraste | Apenas primary, primaryVariant e background |
Pares ricos: Container, OnContainer, Inverse, Outlines | Garantia matemática de legibilidade e acessibilidade |
| Contornos & Cantos (Shapes) | Cantos retangulares ou com raio pequeno padrão | Curvaturas mais expressivas e pílulas completas (shape = CircleShape) |
Aparência moderna, tátil e amigável ao toque |
| Elevação Visual | Controlada por sombras artificiais pesadas (elevation = 8.dp) |
Controlada principalmente por preenchimento de cor tonal (surfaceContainerHigh) |
Economia de GPU e melhor visualização em telas OLED |
| Componentes Nativos | BottomNavigation, TopAppBar genéricos |
NavigationBar, CenterAlignedTopAppBar, LargeTopAppBar |
Suporte imediato a scroll behaviors e comportamentos colapsáveis |
💻 3. Laboratório Prático: Tema Completo com Suporte Dinâmico e Modos Claro/Escuro
O código abaixo define a estrutura oficial recomendada para criar o tema do aplicativo no Jetpack Compose com suporte ao Dynamic Color e fallback seguro para versões anteriores ao Android 12:
package br.com.portal.mobile.android.cap05
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Shapes
import androidx.compose.material3.Typography
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// 1. Paletas Estáticas de Fallback (para Android < 12 ou preferências de marca)
private val DarkCustomColorScheme = darkColorScheme(
primary = Color(0xFFA5C8FF),
onPrimary = Color(0xFF00315F),
primaryContainer = Color(0xFF004785),
onPrimaryContainer = Color(0xFFD4E3FF),
surface = Color(0xFF1A1C1E),
onSurface = Color(0xFFE2E2E6)
)
private val LightCustomColorScheme = lightColorScheme(
primary = Color(0xFF005EB4),
onPrimary = Color(0xFFFFFFFF),
primaryContainer = Color(0xFFD4E3FF),
onPrimaryContainer = Color(0xFF001C3B),
surface = Color(0xFFFDFBFF),
onSurface = Color(0xFF1A1C1E)
)
// 2. Escala Tipográfica Padronizada
val AppTypography = Typography(
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Bold,
fontSize = 22.sp,
lineHeight = 28.sp
),
bodyMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 14.sp,
lineHeight = 20.sp
)
)
// 3. Função de Tema Global da Aplicação
@Composable
fun PortalAndroidTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true, // Ativa cores do wallpaper em Android 12+
content: @Composable () -> Unit
) {
val context = LocalContext.current
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkCustomColorScheme
else -> LightCustomColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = AppTypography,
content = content
)
}
⚠️ 4. Armadilhas Comuns no Uso do Material 3
- Cores Hardcoded em Componentes: Escrever
modifier.background(Color.White)ouText(color = Color.Black)quebra totalmente o suporte ao Dark Mode. Utilize invariavelmenteMaterialTheme.colorScheme.surfaceeMaterialTheme.colorScheme.onSurface. - Misturar Bibliotecas M2 e M3: Certifique-se de importar sempre classes do pacote
androidx.compose.material3.*. Importar artefatos doandroidx.compose.material.*(M2) causa conflitos de temas e inconsistências de renderização visual. - Ignorar Cores Dinâmicas em Telas de Branding: Se sua aplicação possui uma identidade corporativa estrita (por exemplo, um banco que exige estritamente tom vermelho ou laranja), configure
dynamicColor = falsepara impedir que o papel de parede do usuário altere a identidade visual da empresa.