Theming in Jetpack Compose application
What is rememberSystemUiController()
?
How do you theme an app in jetpack compose?
The theme is set at the top level of setContent()
// code to set the theme
@AndroidEntryPoint
class ScaffoldActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NationalParksTheme {
NationalParksApp()
}
}
}
}
How do you define light and dark mode in jetpack compose?
In Theme.kt file, you would define your dark and light theme?
private val LightColors = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = md_theme_light_onPrimaryContainer,
...
)
private val DarkColors = darkColorScheme(
primary = md_theme_dark_primary,
onPrimary = md_theme_dark_onPrimary,
primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
...
)
And you would use it in your theme definition
MaterialTheme(
colorScheme = colorScheme,
shapes = Shapes,
typography = Typography,
content = content
)
The full code for figuring out the colorScheme, shapes, typography and content are
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
val view = LocalView.current
if (!view.isInEditMode) {
val systemUiController = rememberSystemUiController()
val useDarkIcons = !isSystemInDarkTheme()
val window = (view.context as Activity).window
WindowCompat.setDecorFitsSystemWindows(window, false)
DisposableEffect(systemUiController, useDarkIcons) {
// Update all of the system bar colors to be transparent, and use
// dark icons if we're in light theme
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = useDarkIcons
)
onDispose {}
}
}
MaterialTheme(
colorScheme = colorScheme,
shapes = Shapes,
typography = Typography,
content = content
)
In here, it has the logic to handle the dynamicColorTheme, which is a way to using colors based on theme
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
: This condition checks if dynamic color is enabled (dynamicColor
) and if the device's API level is 31 or higher, which corresponds to Android 12 (S) or later. Dynamic color is a feature introduced in Android 12 that allows apps to adapt their colors based on the user's wallpaper 16
How do you set light and dark mode in jetpack compose theme?
The setting of light, dark and dynamic theming happens here
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
How do you define the typography in jetpack compose?
val Typography = Typography(
displaySmall = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 36.sp
),
headlineSmall = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 30.sp
),
labelSmall = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 13.sp
),
titleSmall = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 14.sp
),
titleMedium = TextStyle(
fontWeight = FontWeight.SemiBold,
letterSpacing = (.5).sp,
fontSize = 18.sp
),
titleLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 24.sp
),
)
And it's used as followed:
Text(
text = name,
style = MaterialTheme.typography.displaySmall,
modifier = Modifier
What is shapes in MaterialTheme?
In Jetpack Compose, shapes
within MaterialTheme
refers to the visual appearance of surfaces and elements in your application, defining the corner roundness and overall form of UI components. It is part of the Material Design System and helps in creating visually appealing and consistent UIs.
The shapes
parameter in MaterialTheme
allows you to define a set of common shapes that can be reused throughout your application. These shapes can be applied to various UI components to give them a consistent look and feel. Here's what you need to know about shapes:
// An example of how to design Shapes in Jetpack Compose
val Shapes = Shapes(
small = RoundedCornerShape(
topStart = 0.dp,
topEnd = 12.dp,
bottomStart = 12.dp,
bottomEnd = 0.dp
),
medium = RoundedCornerShape(
topStart = 0.dp,
topEnd = 12.dp,
bottomStart = 12.dp,
bottomEnd = 0.dp
)
// and you would use it as followed
FloatingActionButton(
onClick = onFabClick,
shape = MaterialTheme.shapes.small,
// Semantics in parent due to https://issuetracker.google.com/184825850
modifier = modifier.semantics {
contentDescription = addPlantContentDescription
}
) {
Icon(
Icons.Filled.Add,
contentDescription = null
)
}
What is content in MaterialTheme?
content
is likely a lambda function that defines the content to be displayed within the scope of the MaterialTheme
.
In Jetpack Compose, MaterialTheme
is used to apply a theme to a part of the UI hierarchy. It takes parameters for defining the color scheme, typography, and shapes, among other things. The content
block is where you would place the UI elements that should be styled according to the theme defined in MaterialTheme
.
Here's a general example of how MaterialTheme
might be used with a content
block: