feat: 适配 MD3E 部分动画

This commit is contained in:
Super12138 2025-11-22 20:25:57 +08:00
parent 3487c64fe5
commit 63a7a83071
6 changed files with 52 additions and 39 deletions

View file

@ -10,7 +10,7 @@ enum class Priority(val value: Float) {
NotImportant(-1f),
NotUrgent(-2f);
fun getDisplayName(context: Context): String {
fun displayName(context: Context): String {
val resId = when (this) {
Urgent -> R.string.priority_urgent
Important -> R.string.priority_important

View file

@ -35,7 +35,7 @@ fun TodoPrioritySlider(
val view = LocalView.current
val context = LocalContext.current
val priorityName = remember { Priority.entries.map { it.getDisplayName(context) } }
val priorityName = remember { Priority.entries.map { it.displayName(context) } }
val interactionSource = remember { MutableInteractionSource() }
Slider(

View file

@ -164,8 +164,6 @@ fun MainPage(
},
selectedTodoIds = selectedTodoIds,
modifier = Modifier.fillMaxWidth()
// sharedTransitionScope = sharedTransitionScope,
// animatedVisibilityScope = animatedVisibilityScope,
)
}
/*}*/

View file

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -21,7 +22,7 @@ import cn.super12138.todo.ui.TodoDefaults
import cn.super12138.todo.ui.components.LazyColumnCustomScrollBar
import cn.super12138.todo.ui.pages.main.components.TodoCard
@OptIn(ExperimentalSharedTransitionApi::class)
@OptIn(ExperimentalSharedTransitionApi::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun ManagerFragment(
modifier: Modifier = Modifier,
@ -30,9 +31,7 @@ fun ManagerFragment(
onItemClick: (TodoEntity) -> Unit = {},
onItemLongClick: (TodoEntity) -> Unit = {},
onItemChecked: (TodoEntity) -> Unit = {},
selectedTodoIds: List<Int>,
// sharedTransitionScope: SharedTransitionScope,
// animatedVisibilityScope: AnimatedVisibilityScope
selectedTodoIds: List<Int>
) {
LazyColumnCustomScrollBar(
state = state,
@ -79,11 +78,13 @@ fun ManagerFragment(
onCardClick = { onItemClick(item) },
onCardLongClick = { onItemLongClick(item) },
onChecked = { onItemChecked(item) },
// sharedTransitionScope = sharedTransitionScope,
// animatedVisibilityScope = animatedVisibilityScope,
modifier = Modifier
.padding(vertical = 5.dp)
.animateItem() // TODO: 设置动画时间
.animateItem(
fadeInSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),
placementSpec = MaterialTheme.motionScheme.defaultSpatialSpec(),
fadeOutSpec = MaterialTheme.motionScheme.fastEffectsSpec()
)
)
}
}

View file

@ -2,6 +2,10 @@ package cn.super12138.todo.ui.pages.main.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkHorizontally
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
@ -18,6 +22,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Badge
import androidx.compose.material3.BadgedBox
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@ -38,8 +43,12 @@ import cn.super12138.todo.R
import cn.super12138.todo.logic.model.Priority
import cn.super12138.todo.ui.TodoDefaults
import cn.super12138.todo.utils.VibrationUtils
import cn.super12138.todo.utils.containerColor
@OptIn(ExperimentalFoundationApi::class, ExperimentalSharedTransitionApi::class)
@OptIn(
ExperimentalFoundationApi::class, ExperimentalSharedTransitionApi::class,
ExperimentalMaterial3ExpressiveApi::class
)
@Composable
fun TodoCard(
modifier: Modifier = Modifier,
@ -51,9 +60,7 @@ fun TodoCard(
selected: Boolean,
onCardClick: () -> Unit = {},
onCardLongClick: () -> Unit = {},
onChecked: () -> Unit = {},
// sharedTransitionScope: SharedTransitionScope,
// animatedVisibilityScope: AnimatedVisibilityScope
onChecked: () -> Unit = {}
) {
val view = LocalView.current
val context = LocalContext.current
@ -77,7 +84,15 @@ fun TodoCard(
)
.padding(horizontal = 15.dp)
) {
AnimatedVisibility(selected) {
AnimatedVisibility(
visible = selected,
enter = fadeIn(MaterialTheme.motionScheme.fastSpatialSpec()) + expandHorizontally(
MaterialTheme.motionScheme.fastSpatialSpec()
),
exit = fadeOut(MaterialTheme.motionScheme.fastSpatialSpec()) + shrinkHorizontally(
MaterialTheme.motionScheme.fastSpatialSpec()
)
) {
Box(
Modifier
.padding(end = 15.dp)
@ -102,51 +117,32 @@ fun TodoCard(
BadgedBox(
badge = {
Badge(
containerColor = when (priority) {
Priority.NotUrgent -> MaterialTheme.colorScheme.surfaceContainerHighest
Priority.NotImportant -> MaterialTheme.colorScheme.surfaceContainerHighest
Priority.Default -> MaterialTheme.colorScheme.secondary
Priority.Important -> MaterialTheme.colorScheme.tertiary
Priority.Urgent -> MaterialTheme.colorScheme.error
},
containerColor = priority.containerColor(),
modifier = Modifier.padding(start = 5.dp)
) {
Text(
text = priority.getDisplayName(context),
text = priority.displayName(context),
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
)
}
}
) {
// with(sharedTransitionScope) {
Text(
text = content,
style = MaterialTheme.typography.titleLarge,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
modifier = Modifier
/*.sharedBounds(
sharedContentState = rememberSharedContentState("${Constants.KEY_TODO_CONTENT_TRANSITION}_$id"),
animatedVisibilityScope = animatedVisibilityScope
)*/
.basicMarquee() // TODO: 后续评估性能影响
modifier = Modifier.basicMarquee() // TODO: 后续评估性能影响
)
// }
}
// with(sharedTransitionScope) {
Text(
text = category.ifEmpty { stringResource(R.string.tip_default_category) },
style = MaterialTheme.typography.labelMedium,
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
maxLines = 1,
/*modifier = Modifier.sharedBounds(
sharedContentState = rememberSharedContentState("${Constants.KEY_TODO_CATEGORY_TRANSITION}_$id"),
animatedVisibilityScope = animatedVisibilityScope
)*/
maxLines = 1
)
// }
}
AnimatedVisibility(!selected && !completed) {

View file

@ -0,0 +1,18 @@
package cn.super12138.todo.utils
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import cn.super12138.todo.logic.model.Priority
@Composable
@Stable
fun Priority.containerColor(): Color =
when (this) {
Priority.NotUrgent -> MaterialTheme.colorScheme.surfaceContainerHighest
Priority.NotImportant -> MaterialTheme.colorScheme.surfaceContainerHighest
Priority.Default -> MaterialTheme.colorScheme.secondary
Priority.Important -> MaterialTheme.colorScheme.tertiary
Priority.Urgent -> MaterialTheme.colorScheme.error
}