feat: Improve UI and theme handling

This commit introduces several UI and theming enhancements:

- Adds labels to the "Dark theme" and "Dynamic theme" switches for better clarity.
- Implements dynamic status bar icon colors to match the current theme (light/dark), improving system integration.
- Enhances the color grid items by:
    - Automatically calculating and applying a contrasting content color (text and border) for better readability against the background color.
    - Displaying the hex code of the color.
- Bumps the Compose BOM version to `2025.12.00`.
This commit is contained in:
2025-12-16 11:47:20 +03:00
parent 9d5e53314c
commit 817d3919e2
3 changed files with 64 additions and 21 deletions
@@ -42,11 +42,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.graphics.ColorUtils
import dev.meloda.app.materialcolors.ui.theme.AppTheme
class MainActivity : ComponentActivity() {
@@ -66,7 +68,7 @@ fun RootContent() {
AppTheme(
darkTheme = dark,
dynamicColor = dynamic
dynamicColor = dynamic,
) {
Scaffold(modifier = Modifier.fillMaxSize()) { padding ->
Column(
@@ -78,14 +80,21 @@ fun RootContent() {
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Switch(
checked = dark,
onCheckedChange = { dark = it },
)
Switch(
checked = dynamic,
onCheckedChange = { dynamic = it },
)
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Dark theme")
Switch(
checked = dark,
onCheckedChange = { dark = it },
)
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "Dynamic theme")
Switch(
checked = dynamic,
onCheckedChange = { dynamic = it },
)
}
}
ColorsGrid()
@@ -187,9 +196,9 @@ fun ColorsGrid(
@Composable
private fun ColorGridItem(
modifier: Modifier = Modifier,
title: String,
color: ULong
color: ULong,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
val animatedColor by animateColorAsState(
@@ -197,7 +206,34 @@ private fun ColorGridItem(
label = "animate color"
)
val shape = RoundedCornerShape(25)
val shape = remember {
RoundedCornerShape(25)
}
val color = remember(color) {
Color(color)
}
val isLight = remember(color) {
ColorUtils.calculateLuminance(color.toArgb()) >= 0.5f
}
val hex = remember(color) {
"#%02X%02X%02X".format(
(color.red * 255).toInt(),
(color.green * 255).toInt(),
(color.blue * 255).toInt()
)
}
val borderColor by animateColorAsState(
targetValue = if (isLight) Color.DarkGray else Color.LightGray,
label = "borderColor"
)
val contentColor by animateColorAsState(
targetValue = MaterialTheme.colorScheme.contentColorFor(Color(color.value))
.takeIf { it != Color.Unspecified } ?: if (isLight) Color.Black else Color.White,
label = "contentColor"
)
Box(
modifier = modifier
@@ -205,16 +241,10 @@ private fun ColorGridItem(
.background(color = animatedColor)
.border(
width = 1.dp,
color = Color(0xffCCCCCC),
color = borderColor,
shape = shape
)
.clickable {
val color = Color(color)
val hex = "#%02X%02X%02X".format(
(color.red * 255).toInt(),
(color.green * 255).toInt(),
(color.blue * 255).toInt()
)
Log.d("Material Colors", "picked color: $hex")
(context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager)
@@ -233,7 +263,7 @@ private fun ColorGridItem(
Text(
text = title,
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.contentColorFor(Color(color)),
color = contentColor,
style = MaterialTheme.typography.labelSmall,
fontSize = 12.sp,
letterSpacing = 0.sp,
@@ -1,5 +1,6 @@
package dev.meloda.app.materialcolors.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
@@ -8,7 +9,10 @@ import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat
@Composable
fun AppTheme(
@@ -26,6 +30,15 @@ fun AppTheme(
else -> lightColorScheme()
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
val insetsController = WindowCompat.getInsetsController(window, view)
insetsController.isAppearanceLightStatusBars = !darkTheme
}
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
+1 -1
View File
@@ -4,7 +4,7 @@ kotlin = "2.2.0"
coreKtx = "1.16.0"
lifecycleRuntimeKtx = "2.9.1"
activityCompose = "1.10.1"
composeBom = "2025.06.01"
composeBom = "2025.12.00"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }