feat: 适配 MD3E 部分动画
This commit is contained in:
parent
3487c64fe5
commit
63a7a83071
6 changed files with 52 additions and 39 deletions
|
|
@ -10,7 +10,7 @@ enum class Priority(val value: Float) {
|
||||||
NotImportant(-1f),
|
NotImportant(-1f),
|
||||||
NotUrgent(-2f);
|
NotUrgent(-2f);
|
||||||
|
|
||||||
fun getDisplayName(context: Context): String {
|
fun displayName(context: Context): String {
|
||||||
val resId = when (this) {
|
val resId = when (this) {
|
||||||
Urgent -> R.string.priority_urgent
|
Urgent -> R.string.priority_urgent
|
||||||
Important -> R.string.priority_important
|
Important -> R.string.priority_important
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ fun TodoPrioritySlider(
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
val context = LocalContext.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() }
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|
||||||
Slider(
|
Slider(
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,6 @@ fun MainPage(
|
||||||
},
|
},
|
||||||
selectedTodoIds = selectedTodoIds,
|
selectedTodoIds = selectedTodoIds,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
// sharedTransitionScope = sharedTransitionScope,
|
|
||||||
// animatedVisibilityScope = animatedVisibilityScope,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/*}*/
|
/*}*/
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.components.LazyColumnCustomScrollBar
|
||||||
import cn.super12138.todo.ui.pages.main.components.TodoCard
|
import cn.super12138.todo.ui.pages.main.components.TodoCard
|
||||||
|
|
||||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
@OptIn(ExperimentalSharedTransitionApi::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagerFragment(
|
fun ManagerFragment(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -30,9 +31,7 @@ fun ManagerFragment(
|
||||||
onItemClick: (TodoEntity) -> Unit = {},
|
onItemClick: (TodoEntity) -> Unit = {},
|
||||||
onItemLongClick: (TodoEntity) -> Unit = {},
|
onItemLongClick: (TodoEntity) -> Unit = {},
|
||||||
onItemChecked: (TodoEntity) -> Unit = {},
|
onItemChecked: (TodoEntity) -> Unit = {},
|
||||||
selectedTodoIds: List<Int>,
|
selectedTodoIds: List<Int>
|
||||||
// sharedTransitionScope: SharedTransitionScope,
|
|
||||||
// animatedVisibilityScope: AnimatedVisibilityScope
|
|
||||||
) {
|
) {
|
||||||
LazyColumnCustomScrollBar(
|
LazyColumnCustomScrollBar(
|
||||||
state = state,
|
state = state,
|
||||||
|
|
@ -79,11 +78,13 @@ fun ManagerFragment(
|
||||||
onCardClick = { onItemClick(item) },
|
onCardClick = { onItemClick(item) },
|
||||||
onCardLongClick = { onItemLongClick(item) },
|
onCardLongClick = { onItemLongClick(item) },
|
||||||
onChecked = { onItemChecked(item) },
|
onChecked = { onItemChecked(item) },
|
||||||
// sharedTransitionScope = sharedTransitionScope,
|
|
||||||
// animatedVisibilityScope = animatedVisibilityScope,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(vertical = 5.dp)
|
.padding(vertical = 5.dp)
|
||||||
.animateItem() // TODO: 设置动画时间
|
.animateItem(
|
||||||
|
fadeInSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),
|
||||||
|
placementSpec = MaterialTheme.motionScheme.defaultSpatialSpec(),
|
||||||
|
fadeOutSpec = MaterialTheme.motionScheme.fastEffectsSpec()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ package cn.super12138.todo.ui.pages.main.components
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
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.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.basicMarquee
|
import androidx.compose.foundation.basicMarquee
|
||||||
|
|
@ -18,6 +22,7 @@ import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material3.Badge
|
import androidx.compose.material3.Badge
|
||||||
import androidx.compose.material3.BadgedBox
|
import androidx.compose.material3.BadgedBox
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
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.logic.model.Priority
|
||||||
import cn.super12138.todo.ui.TodoDefaults
|
import cn.super12138.todo.ui.TodoDefaults
|
||||||
import cn.super12138.todo.utils.VibrationUtils
|
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
|
@Composable
|
||||||
fun TodoCard(
|
fun TodoCard(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -51,9 +60,7 @@ fun TodoCard(
|
||||||
selected: Boolean,
|
selected: Boolean,
|
||||||
onCardClick: () -> Unit = {},
|
onCardClick: () -> Unit = {},
|
||||||
onCardLongClick: () -> Unit = {},
|
onCardLongClick: () -> Unit = {},
|
||||||
onChecked: () -> Unit = {},
|
onChecked: () -> Unit = {}
|
||||||
// sharedTransitionScope: SharedTransitionScope,
|
|
||||||
// animatedVisibilityScope: AnimatedVisibilityScope
|
|
||||||
) {
|
) {
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
@ -77,7 +84,15 @@ fun TodoCard(
|
||||||
)
|
)
|
||||||
.padding(horizontal = 15.dp)
|
.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(
|
Box(
|
||||||
Modifier
|
Modifier
|
||||||
.padding(end = 15.dp)
|
.padding(end = 15.dp)
|
||||||
|
|
@ -102,51 +117,32 @@ fun TodoCard(
|
||||||
BadgedBox(
|
BadgedBox(
|
||||||
badge = {
|
badge = {
|
||||||
Badge(
|
Badge(
|
||||||
containerColor = when (priority) {
|
containerColor = priority.containerColor(),
|
||||||
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
|
|
||||||
},
|
|
||||||
modifier = Modifier.padding(start = 5.dp)
|
modifier = Modifier.padding(start = 5.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = priority.getDisplayName(context),
|
text = priority.displayName(context),
|
||||||
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
|
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
// with(sharedTransitionScope) {
|
|
||||||
Text(
|
Text(
|
||||||
text = content,
|
text = content,
|
||||||
style = MaterialTheme.typography.titleLarge,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
|
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
|
||||||
modifier = Modifier
|
modifier = Modifier.basicMarquee() // TODO: 后续评估性能影响
|
||||||
/*.sharedBounds(
|
|
||||||
sharedContentState = rememberSharedContentState("${Constants.KEY_TODO_CONTENT_TRANSITION}_$id"),
|
|
||||||
animatedVisibilityScope = animatedVisibilityScope
|
|
||||||
)*/
|
|
||||||
.basicMarquee() // TODO: 后续评估性能影响
|
|
||||||
)
|
)
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// with(sharedTransitionScope) {
|
|
||||||
Text(
|
Text(
|
||||||
text = category.ifEmpty { stringResource(R.string.tip_default_category) },
|
text = category.ifEmpty { stringResource(R.string.tip_default_category) },
|
||||||
style = MaterialTheme.typography.labelMedium,
|
style = MaterialTheme.typography.labelMedium,
|
||||||
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
|
textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None,
|
||||||
maxLines = 1,
|
maxLines = 1
|
||||||
/*modifier = Modifier.sharedBounds(
|
|
||||||
sharedContentState = rememberSharedContentState("${Constants.KEY_TODO_CATEGORY_TRANSITION}_$id"),
|
|
||||||
animatedVisibilityScope = animatedVisibilityScope
|
|
||||||
)*/
|
|
||||||
)
|
)
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(!selected && !completed) {
|
AnimatedVisibility(!selected && !completed) {
|
||||||
|
|
|
||||||
18
app/src/main/kotlin/cn/super12138/todo/utils/TodoExt.kt
Normal file
18
app/src/main/kotlin/cn/super12138/todo/utils/TodoExt.kt
Normal 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
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue