UI com Material Design

Tempo: 25 min Nível: Intermediário

Princípios do Material Design

Fundamentos
  • Hierarquia visual clara
  • Feedback tátil significativo
  • Animações com propósito
  • Adaptabilidade a diferentes dispositivos
Recursos Chave
Temas Tipografia Componentes Dark Mode Motion Acessibilidade

Configuração Inicial

Adicione estas dependências no build.gradle (Module)
build.gradle
dependencies {
    implementation 'com.google.android.material:material:1.9.0'
    
    // Para temas dinâmicos
    implementation 'androidx.core:core-splashscreen:1.0.1'
    implementation 'androidx.palette:palette-ktx:1.0.0'
}

Atualize seu tema

themes.xml
<style name="Theme.MyApp" parent="Theme.Material3.DayNight">
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorPrimaryVariant">@color/purple_700</item>
    <item name="colorOnPrimary">@color/white</item>
    <item name="colorSecondary">@color/teal_200</item>
    <item name="colorOnSecondary">@color/black</item>
    <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
</style>

Componentes Material

MaterialButton
<com.google.android.material.button.MaterialButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button"
    app:icon="@drawable/ic_add"
    app:iconGravity="textStart"
    app:cornerRadius="8dp"
    style="@style/Widget.Material3.Button.OutlinedButton"/>
TextInputLayout
<com.google.android.material.textfield.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:startIconDrawable="@drawable/ic_email"
    app:helperText="Digite seu email">
    
    <com.google.android.material.textfield.TextInputEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Email"/>
</com.google.android.material.textfield.TextInputLayout>
MaterialCardView
<com.google.android.material.card.MaterialCardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardElevation="4dp"
    app:strokeColor="@color/purple_500"
    app:strokeWidth="1dp">
    
    <!-- Conteúdo -->
</com.google.android.material.card.MaterialCardView>
BottomNavigationView
<com.google.android.material.bottomnavigation.BottomNavigationView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:menu="@menu/bottom_nav_menu"
    app:labelVisibilityMode="labeled"
    app:itemIconTint="@drawable/nav_item_color"
    app:itemTextColor="@drawable/nav_item_color"/>

Dark Mode & Temas Dinâmicos

themes.xml (night)
<style name="Theme.MyApp" parent="Theme.Material3.DayNight">
    <item name="colorPrimary">@color/purple_200</item>
    <item name="colorPrimaryVariant">@color/purple_300</item>
    <item name="colorOnPrimary">@color/black</item>
    <item name="colorSecondary">@color/teal_200</item>
    <item name="android:windowLightStatusBar">false</item>
</style>
ThemeUtils.kt
object ThemeUtils {
    fun applyTheme(themePref: String) {
        when (themePref) {
            "light" -> AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO)
            "dark" -> AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES)
            else -> AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM)
        }
    }
    
    fun getDynamicColor(context: Context, @ColorRes light: Int, @ColorRes dark: Int): Int {
        return ContextCompat.getColor(context, if (isDarkTheme(context)) dark else light)
    }
    
    private fun isDarkTheme(context: Context): Boolean {
        return when (context.resources.configuration.uiMode and 
            Configuration.UI_MODE_NIGHT_MASK) {
            Configuration.UI_MODE_NIGHT_YES -> true
            else -> false
        }
    }
}

Motion & Animações

Shared Element Transition
// Activity de origem
val intent = Intent(this, DetailActivity::class.java)
val options = ActivityOptions.makeSceneTransitionAnimation(
    this,
    imageView, "shared_image"
)
startActivity(intent, options.toBundle())

// Activity de destino
override fun onCreate(savedInstanceState: Bundle?) {
    window.sharedElementEnterTransition = ChangeBounds()
    window.sharedElementReturnTransition = ChangeBounds()
}
MotionLayout
<androidx.constraintlayout.motion.widget.MotionLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_01">
    
    <ImageView
        android:id="@+id/fab"
        android:layout_width="64dp"
        android:layout_height="64dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
</MotionLayout>
Dica: Use a biblioteca androidx.constraintlayout:constraintlayout:2.1.0+ para animações avançadas com MotionLayout.

Recursos Adicionais

Kit UI Completo

Componentes prontos para usar

Baixar
Color Tool

Gerador de paletas de cores

Acessar
Material Gallery

App com exemplos oficiais

Ver
Conclusão
O que aprendemos:
  • Configurar Material Components
  • Implementar temas light/dark
  • Usar componentes modernos
  • Criar animações fluidas

Próximos passos: