Step 8 of 15
MaterialTheme, color schemes, typography, shapes, dark theme, dynamicColor
Theming และ Material 3 — color schemes, typography, dark mode, dynamic color
MaterialTheme wraps your app and provides colors, typography, and shapes. Every Material 3 composable reads these values automatically.
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun MyApp(content: @Composable () -> Unit) {
TaskManagerTheme {
Surface { content() }
}
}
Surface applies the theme's background color. Text picks up the theme's on-surface color without extra config.
Define a lightColorScheme and a darkColorScheme. Each sets roles like primary, background, and surface.
import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.ui.graphics.Color
private val LightColors = lightColorScheme(
primary = Color(0xFF6650A4),
onPrimary = Color.White,
secondary = Color(0xFF625B71),
background = Color(0xFFFFFBFE),
surface = Color(0xFFFFFBFE),
)
private val DarkColors = darkColorScheme(
primary = Color(0xFFD0BCFF),
onPrimary = Color(0xFF381E72),
secondary = Color(0xFFCCC2DC),
background = Color(0xFF1C1B1F),
surface = Color(0xFF1C1B1F),
)
Read the system dark mode with isSystemInDarkTheme() and choose the scheme:
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@Composable
fun TaskManagerTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colors = if (darkTheme) DarkColors else LightColors
MaterialTheme(
colorScheme = colors,
content = content
)
}
Now your app follows the user's system setting automatically.
On Android 12 and later, dynamic color derives the palette from the user's wallpaper. Use dynamicLightColorScheme and dynamicDarkColorScheme:
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
@Composable
fun TaskManagerTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val context = LocalContext.current
val colors = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
if (darkTheme) dynamicDarkColorScheme(context)
else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
MaterialTheme(colorScheme = colors, content = content)
}
Define text styles in a Typography object:
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
val AppTypography = Typography(
titleLarge = TextStyle(
fontSize = 22.sp,
fontWeight = FontWeight.Bold
),
bodyLarge = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Normal
)
)
// Usage
MaterialTheme(
colorScheme = colors,
typography = AppTypography,
content = content
)
Then use the styles by role:
Text("My Tasks", style = MaterialTheme.typography.titleLarge)
Text("5 pending", style = MaterialTheme.typography.bodyLarge)
Control corner roundness with Shapes:
import androidx.compose.material3.Shapes
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.unit.dp
val AppShapes = Shapes(
small = RoundedCornerShape(8.dp),
medium = RoundedCornerShape(16.dp),
large = RoundedCornerShape(24.dp)
)
MaterialTheme(shapes = AppShapes, content = content)
Card, Button, and TextField now use these corner radii.
Read any theme value with MaterialTheme.colorScheme, MaterialTheme.typography, or MaterialTheme.shapes:
Box(
modifier = Modifier
.background(MaterialTheme.colorScheme.surfaceVariant)
.padding(16.dp)
) {
Text("Themed", color = MaterialTheme.colorScheme.onSurfaceVariant)
}
Create a custom theme with a teal primary color, a titleLarge style of 28sp bold, and medium shape of 20dp corners. Apply it to a Card containing a title and a body text. Toggle the system dark mode and confirm both themes look correct.