diff --git a/app/src/main/kotlin/cn/super12138/todo/constants/Constants.kt b/app/src/main/kotlin/cn/super12138/todo/constants/Constants.kt index e7f7195..501334f 100644 --- a/app/src/main/kotlin/cn/super12138/todo/constants/Constants.kt +++ b/app/src/main/kotlin/cn/super12138/todo/constants/Constants.kt @@ -5,6 +5,7 @@ object Constants { const val GITHUB_REPO = "https://github.com/Super12138/ToDo/" const val KEY_TODO_FAB_TRANSITION = "todo_fab" + const val KEY_TODO_CONTENT_TRANSITION = "todo_content" const val SP_NAME = "cn.super12138.todo_preferences" diff --git a/app/src/main/kotlin/cn/super12138/todo/ui/navigation/TodoNavigation.kt b/app/src/main/kotlin/cn/super12138/todo/ui/navigation/TodoNavigation.kt index e88029b..a4fda68 100644 --- a/app/src/main/kotlin/cn/super12138/todo/ui/navigation/TodoNavigation.kt +++ b/app/src/main/kotlin/cn/super12138/todo/ui/navigation/TodoNavigation.kt @@ -70,7 +70,7 @@ fun TodoNavigation( toDo = viewModel.selectedEditTodo, onSave = { viewModel.addTodo(it) - viewModel.setEditTodoItem(null) + // viewModel.setEditTodoItem(null) navController.navigateUp() }, onDelete = { @@ -82,7 +82,7 @@ fun TodoNavigation( }, onNavigateUp = { navController.navigateUp() - viewModel.setEditTodoItem(null) + // viewModel.setEditTodoItem(null) }, sharedTransitionScope = this@SharedTransitionLayout, animatedVisibilityScope = this@composable diff --git a/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/TodoEditorPage.kt b/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/TodoEditorPage.kt index 070d70f..ce6a413 100644 --- a/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/TodoEditorPage.kt +++ b/app/src/main/kotlin/cn/super12138/todo/ui/pages/editor/TodoEditorPage.kt @@ -66,7 +66,7 @@ fun TodoEditorPage( animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier ) { - BackHandler { + BackHandler { // TODO: 实现用户更改后的阻止返回 onNavigateUp() } val context = LocalContext.current @@ -141,18 +141,25 @@ fun TodoEditorPage( .fillMaxSize() .verticalScroll(rememberScrollState()) ) { - TextField( - value = text, - onValueChange = { text = it }, - label = { Text(stringResource(R.string.placeholder_add_todo)) }, - isError = isError, - supportingText = { - AnimatedVisibility(isError) { - Text(stringResource(R.string.error_no_task_content)) - } - }, - modifier = Modifier.fillMaxWidth() - ) + with(sharedTransitionScope) { + TextField( + value = text, + onValueChange = { text = it }, + label = { Text(stringResource(R.string.placeholder_add_todo)) }, + isError = isError, + supportingText = { + AnimatedVisibility(isError) { + Text(stringResource(R.string.error_no_task_content)) + } + }, + modifier = Modifier + .fillMaxWidth() + .sharedBounds( + sharedContentState = rememberSharedContentState("${Constants.KEY_TODO_CONTENT_TRANSITION}_${toDo?.id}"), + animatedVisibilityScope = animatedVisibilityScope + ) + ) + } Spacer(Modifier.size(5.dp)) 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 27e41a3..faa2612 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 @@ -95,7 +95,10 @@ fun MainPage( ) { TodoFAB( expanded = isExpanded, - onClick = toTodoEditPage, + onClick = { + viewModel.setEditTodoItem(null) // 每次添加待办前清除上一次已选待办 + toTodoEditPage() + }, modifier = Modifier.sharedElement( state = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION), animatedVisibilityScope = animatedVisibilityScope @@ -146,6 +149,8 @@ fun MainPage( } }, selectedTodoIds = selectedTodoIds.value, + sharedTransitionScope = sharedTransitionScope, + animatedVisibilityScope = animatedVisibilityScope, modifier = Modifier .weight(3f) .fillMaxSize() @@ -189,6 +194,8 @@ fun MainPage( } }, selectedTodoIds = selectedTodoIds.value, + sharedTransitionScope = sharedTransitionScope, + animatedVisibilityScope = animatedVisibilityScope, modifier = Modifier .weight(3f) .fillMaxSize() 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 1869831..11cd281 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 @@ -1,5 +1,8 @@ package cn.super12138.todo.ui.pages.main +import androidx.compose.animation.AnimatedVisibilityScope +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionScope import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -24,6 +27,7 @@ import cn.super12138.todo.ui.pages.main.components.TodoCard import my.nanihadesuka.compose.LazyColumnScrollbar import my.nanihadesuka.compose.ScrollbarSettings +@OptIn(ExperimentalSharedTransitionApi::class) @Composable fun ManagerFragment( state: LazyListState, @@ -32,6 +36,8 @@ fun ManagerFragment( onItemLongClick: (TodoEntity) -> Unit = {}, onItemChecked: (TodoEntity) -> Unit = {}, selectedTodoIds: List, + sharedTransitionScope: SharedTransitionScope, + animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier ) { val context = LocalContext.current @@ -66,6 +72,7 @@ fun ManagerFragment( key = { it.id } ) { item -> TodoCard( + id = item.id, content = item.content, subject = Subjects.fromId(item.subject).getDisplayName(context), completed = item.isCompleted, @@ -74,6 +81,8 @@ fun ManagerFragment( onCardClick = { onItemClick(item) }, onCardLongClick = { onItemLongClick(item) }, onChecked = { onItemChecked(item) }, + sharedTransitionScope = sharedTransitionScope, + animatedVisibilityScope = animatedVisibilityScope, modifier = Modifier .padding(vertical = 5.dp) .animateItem() // TODO: 设置动画时间 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 c582866..0fcefbf 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 @@ -1,6 +1,9 @@ package cn.super12138.todo.ui.pages.main.components import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.AnimatedVisibilityScope +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionScope import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.basicMarquee @@ -31,14 +34,15 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import cn.super12138.todo.R +import cn.super12138.todo.constants.Constants import cn.super12138.todo.logic.model.Priority -@OptIn(ExperimentalFoundationApi::class) +@OptIn(ExperimentalFoundationApi::class, ExperimentalSharedTransitionApi::class) @Composable fun TodoCard( + id: Int, content: String, subject: String, completed: Boolean, @@ -47,6 +51,8 @@ fun TodoCard( onCardClick: () -> Unit = {}, onCardLongClick: () -> Unit = {}, onChecked: () -> Unit = {}, + sharedTransitionScope: SharedTransitionScope, + animatedVisibilityScope: AnimatedVisibilityScope, modifier: Modifier = Modifier ) { val context = LocalContext.current @@ -103,14 +109,21 @@ fun TodoCard( } } ) { - Text( - text = content, - style = MaterialTheme.typography.titleLarge, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textDecoration = if (completed) TextDecoration.LineThrough else TextDecoration.None, - modifier = Modifier.basicMarquee() // TODO: 后续评估性能影响 - ) + 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: 后续评估性能影响 + ) + } } Text( @@ -151,6 +164,7 @@ fun TodoCard( } } +/* @Preview(locale = "zh-rCN", showBackground = true) @Composable private fun TodoCardPreview() { @@ -162,6 +176,8 @@ private fun TodoCardPreview() { selected = false, onCardClick = {}, onCardLongClick = {}, - onChecked = {} + onChecked = {}, + sharedTransitionScope = , + animatedVisibilityScope = ) -} \ No newline at end of file +}*/