mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: migrate to Material 3 Expressive APIs (#4934)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
c259c76550
commit
141b54ff9c
12 changed files with 112 additions and 103 deletions
|
|
@ -23,6 +23,7 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -39,7 +40,7 @@ import org.meshtastic.core.resources.Res
|
|||
import org.meshtastic.core.resources.ic_meshtastic
|
||||
import org.meshtastic.core.resources.navigate_back
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainAppBar(
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -54,26 +55,25 @@ fun MainAppBar(
|
|||
) {
|
||||
TopAppBar(
|
||||
title = {
|
||||
androidx.compose.foundation.layout.Column {
|
||||
Text(
|
||||
text = title,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
},
|
||||
subtitle = {
|
||||
subtitle?.let {
|
||||
Text(
|
||||
text = title,
|
||||
text = it,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
subtitle?.let {
|
||||
Text(
|
||||
text = it,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = modifier,
|
||||
navigationIcon =
|
||||
if (canNavigateUp) {
|
||||
{
|
||||
IconButton(onClick = onNavigateUp) {
|
||||
|
|
|
|||
|
|
@ -16,34 +16,23 @@
|
|||
*/
|
||||
package org.meshtastic.core.ui.component
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.rounded.OfflineShare
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.FloatingActionButtonMenu
|
||||
import androidx.compose.material3.FloatingActionButtonMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SmallFloatingActionButton
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.ToggleFloatingActionButton
|
||||
import androidx.compose.material3.ToggleFloatingActionButtonDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun MenuFAB(
|
||||
expanded: Boolean,
|
||||
|
|
@ -53,61 +42,31 @@ fun MenuFAB(
|
|||
contentDescription: String? = null,
|
||||
testTag: String? = null,
|
||||
) {
|
||||
Column(
|
||||
FloatingActionButtonMenu(
|
||||
modifier = modifier.then(if (testTag != null) Modifier.testTag(testTag) else Modifier),
|
||||
expanded = expanded,
|
||||
button = {
|
||||
ToggleFloatingActionButton(
|
||||
checked = expanded,
|
||||
onCheckedChange = onExpandedChange,
|
||||
content = {
|
||||
val imageVector = if (expanded) Icons.Filled.Close else Icons.AutoMirrored.Rounded.OfflineShare
|
||||
Icon(imageVector = imageVector, contentDescription = contentDescription)
|
||||
},
|
||||
containerColor = ToggleFloatingActionButtonDefaults.containerColor(),
|
||||
)
|
||||
},
|
||||
horizontalAlignment = Alignment.End,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = expanded,
|
||||
enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
|
||||
exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 }),
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.End,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
) {
|
||||
items.forEach { item ->
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
modifier = if (item.testTag != null) Modifier.testTag(item.testTag) else Modifier,
|
||||
) {
|
||||
Surface(
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
modifier = Modifier.padding(end = 8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = item.label,
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
)
|
||||
}
|
||||
SmallFloatingActionButton(
|
||||
onClick = {
|
||||
item.onClick()
|
||||
onExpandedChange(false)
|
||||
},
|
||||
) {
|
||||
Icon(item.icon, contentDescription = item.label)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val rotation by animateFloatAsState(targetValue = if (expanded) 180f else 0f, label = "fab_rotation")
|
||||
|
||||
FloatingActionButton(
|
||||
onClick = { onExpandedChange(!expanded) },
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = if (expanded) Icons.Filled.Close else Icons.AutoMirrored.Rounded.OfflineShare,
|
||||
contentDescription = contentDescription,
|
||||
modifier = Modifier.rotate(rotation),
|
||||
items.forEach { item ->
|
||||
FloatingActionButtonMenuItem(
|
||||
modifier = if (item.testTag != null) Modifier.testTag(item.testTag) else Modifier,
|
||||
onClick = {
|
||||
item.onClick()
|
||||
onExpandedChange(false)
|
||||
},
|
||||
icon = { Icon(item.icon, contentDescription = null) },
|
||||
text = { Text(item.label) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
package org.meshtastic.core.ui.theme
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialExpressiveTheme
|
||||
import androidx.compose.material3.MotionScheme.Companion.expressive
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
|
|
@ -265,6 +267,7 @@ data class ColorFamily(val color: Color, val onColor: Color, val colorContainer:
|
|||
|
||||
val unspecified_scheme = ColorFamily(Color.Unspecified, Color.Unspecified, Color.Unspecified, Color.Unspecified)
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun AppTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
|
|
@ -276,7 +279,12 @@ fun AppTheme(
|
|||
val dynamicScheme = if (dynamicColor) dynamicColorScheme(darkTheme) else null
|
||||
val colorScheme = dynamicScheme ?: if (darkTheme) darkScheme else lightScheme
|
||||
|
||||
MaterialTheme(colorScheme = colorScheme, typography = AppTypography, content = content)
|
||||
MaterialExpressiveTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = AppTypography,
|
||||
motionScheme = expressive(),
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
const val MODE_DYNAMIC = 6969420
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue