From 63a7a830715223d54ccef2becbf04ad6ca00f347 Mon Sep 17 00:00:00 2001 From: Super12138 <70494801+Super12138@users.noreply.github.com> Date: Sat, 22 Nov 2025 20:25:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8D=20MD3E=20=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../super12138/todo/logic/model/Priority.kt | 2 +- .../editor/components/TodoPrioritySlider.kt | 2 +- .../super12138/todo/ui/pages/main/MainPage.kt | 2 - .../todo/ui/pages/main/ManagerFragment.kt | 15 +++--- .../todo/ui/pages/main/components/TodoCard.kt | 52 +++++++++---------- .../cn/super12138/todo/utils/TodoExt.kt | 18 +++++++ 6 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 app/src/main/kotlin/cn/super12138/todo/utils/TodoExt.kt diff --git a/app/src/main/kotlin/cn/super12138/todo/logic/model/Priority.kt b/app/src/main/kotlin/cn/super12138/todo/logic/model/Priority.kt index 395cbe1..b2eb31e 100644 --- a/app/src/main/kotlin/cn/super12138/todo/logic/model/Priority.kt +++ b/app/src/main/kotlin/cn/super12138/todo/logic/model/Priority.kt @@ -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 diff --git a/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/components/TodoPrioritySlider.kt b/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/components/TodoPrioritySlider.kt index 4b416bc..008a182 100644 --- a/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/components/TodoPrioritySlider.kt +++ b/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/components/TodoPrioritySlider.kt @@ -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( diff --git a/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/MainPage.kt b/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/MainPage.kt index af8eadc..3bc62b1 100644 --- a/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/MainPage.kt +++ b/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/MainPage.kt @@ -164,8 +164,6 @@ fun MainPage( }, selectedTodoIds = selectedTodoIds, modifier = Modifier.fillMaxWidth() - // sharedTransitionScope = sharedTransitionScope, - // animatedVisibilityScope = animatedVisibilityScope, ) } /*}*/ diff --git a/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/ManagerFragment.kt b/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/ManagerFragment.kt index c223134..04c95b5 100644 --- a/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/ManagerFragment.kt +++ b/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/ManagerFragment.kt @@ -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, - // sharedTransitionScope: SharedTransitionScope, - // animatedVisibilityScope: AnimatedVisibilityScope + selectedTodoIds: List ) { 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() + ) ) } } diff --git a/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/components/TodoCard.kt b/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/components/TodoCard.kt index a232388..2c7c960 100644 --- a/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/components/TodoCard.kt +++ b/app/src/main/kotlin/cn/super12138/todo/ui/pages/main/components/TodoCard.kt @@ -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) { diff --git a/app/src/main/kotlin/cn/super12138/todo/utils/TodoExt.kt b/app/src/main/kotlin/cn/super12138/todo/utils/TodoExt.kt new file mode 100644 index 0000000..65d5c37 --- /dev/null +++ b/app/src/main/kotlin/cn/super12138/todo/utils/TodoExt.kt @@ -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 + } \ No newline at end of file