feat(main, editor): 更加丝滑的 FAB 过渡动画
This commit is contained in:
parent
3ce8e5befa
commit
4d432935b3
5 changed files with 168 additions and 127 deletions
|
|
@ -4,6 +4,8 @@ object Constants {
|
|||
const val DEVELOPER_GITHUB = "https://github.com/Super12138/"
|
||||
const val GITHUB_REPO = "https://github.com/Super12138/ToDo/"
|
||||
|
||||
const val KEY_TODO_FAB_TRANSITION = "todo_fab"
|
||||
|
||||
const val SP_NAME = "cn.super12138.todo_preferences"
|
||||
|
||||
const val PREF_DYNAMIC_COLOR = "dynamic_color"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package cn.super12138.todo.ui.navigation
|
||||
|
||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||
import androidx.compose.animation.SharedTransitionLayout
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
|
|
@ -19,6 +21,7 @@ import cn.super12138.todo.ui.viewmodels.MainViewModel
|
|||
|
||||
private const val INITIAL_OFFSET_FACTOR = 0.10f
|
||||
|
||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
fun TodoNavigation(
|
||||
navController: NavHostController = rememberNavController(),
|
||||
|
|
@ -26,6 +29,7 @@ fun TodoNavigation(
|
|||
viewModel: MainViewModel,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
SharedTransitionLayout {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = startDestination,
|
||||
|
|
@ -55,7 +59,9 @@ fun TodoNavigation(
|
|||
MainPage(
|
||||
viewModel = viewModel,
|
||||
toTodoEditPage = { navController.navigate(TodoScreen.TodoEditor.name) },
|
||||
toSettingsPage = { navController.navigate(TodoScreen.SettingsMain.name) }
|
||||
toSettingsPage = { navController.navigate(TodoScreen.SettingsMain.name) },
|
||||
sharedTransitionScope = this@SharedTransitionLayout,
|
||||
animatedVisibilityScope = this@composable
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +83,9 @@ fun TodoNavigation(
|
|||
onNavigateUp = {
|
||||
navController.navigateUp()
|
||||
viewModel.setEditTodoItem(null)
|
||||
}
|
||||
},
|
||||
sharedTransitionScope = this@SharedTransitionLayout,
|
||||
animatedVisibilityScope = this@composable
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -118,3 +126,4 @@ fun TodoNavigation(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@ package cn.super12138.todo.ui.pages.editor
|
|||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.AnimatedVisibilityScope
|
||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||
import androidx.compose.animation.SharedTransitionScope
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
|
@ -43,6 +46,7 @@ import androidx.compose.ui.semantics.contentDescription
|
|||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cn.super12138.todo.R
|
||||
import cn.super12138.todo.constants.Constants
|
||||
import cn.super12138.todo.logic.database.TodoEntity
|
||||
import cn.super12138.todo.logic.model.Priority
|
||||
import cn.super12138.todo.logic.model.Subjects
|
||||
|
|
@ -51,13 +55,15 @@ import cn.super12138.todo.ui.components.AnimatedExtendedFloatingActionButton
|
|||
import cn.super12138.todo.ui.components.FilterChipGroup
|
||||
import cn.super12138.todo.ui.components.LargeTopAppBarScaffold
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
fun TodoEditorPage(
|
||||
toDo: TodoEntity? = null,
|
||||
onSave: (TodoEntity) -> Unit,
|
||||
onDelete: () -> Unit,
|
||||
onNavigateUp: () -> Unit,
|
||||
sharedTransitionScope: SharedTransitionScope,
|
||||
animatedVisibilityScope: AnimatedVisibilityScope,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
BackHandler {
|
||||
|
|
@ -75,6 +81,7 @@ fun TodoEditorPage(
|
|||
title = stringResource(if (toDo != null) R.string.title_edit_task else R.string.action_add_task),
|
||||
scrollBehavior = scrollBehavior,
|
||||
floatingActionButton = {
|
||||
with(sharedTransitionScope) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
if (toDo !== null) {
|
||||
AnimatedExtendedFloatingActionButton(
|
||||
|
|
@ -115,8 +122,13 @@ fun TodoEditorPage(
|
|||
id = toDo?.id ?: 0
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.sharedElement(
|
||||
state = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION),
|
||||
animatedVisibilityScope = animatedVisibilityScope
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
onBack = onNavigateUp,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package cn.super12138.todo.ui.pages.main
|
|||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.AnimatedVisibilityScope
|
||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||
import androidx.compose.animation.SharedTransitionScope
|
||||
import androidx.compose.animation.expandIn
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
|
|
@ -27,17 +30,21 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.window.core.layout.WindowWidthSizeClass
|
||||
import cn.super12138.todo.constants.Constants
|
||||
import cn.super12138.todo.logic.database.TodoEntity
|
||||
import cn.super12138.todo.ui.pages.main.components.TodoDeleteConfirmDialog
|
||||
import cn.super12138.todo.ui.pages.main.components.TodoFAB
|
||||
import cn.super12138.todo.ui.pages.main.components.TodoTopAppBar
|
||||
import cn.super12138.todo.ui.viewmodels.MainViewModel
|
||||
|
||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
fun MainPage(
|
||||
viewModel: MainViewModel,
|
||||
toTodoEditPage: () -> Unit,
|
||||
toSettingsPage: () -> Unit,
|
||||
sharedTransitionScope: SharedTransitionScope,
|
||||
animatedVisibilityScope: AnimatedVisibilityScope,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val toDoList = viewModel.toDos.collectAsState(initial = emptyList())
|
||||
|
|
@ -80,6 +87,7 @@ fun MainPage(
|
|||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
with(sharedTransitionScope) {
|
||||
AnimatedVisibility(
|
||||
visible = isSelectedIdsEmpty,
|
||||
enter = fadeIn() + expandIn(),
|
||||
|
|
@ -87,8 +95,13 @@ fun MainPage(
|
|||
) {
|
||||
TodoFAB(
|
||||
expanded = isExpanded,
|
||||
onClick = toTodoEditPage
|
||||
onClick = toTodoEditPage,
|
||||
modifier = Modifier.sharedElement(
|
||||
state = rememberSharedContentState(key = Constants.KEY_TODO_FAB_TRANSITION),
|
||||
animatedVisibilityScope = animatedVisibilityScope
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
contentWindowInsets = WindowInsets.safeContent.exclude(WindowInsets.ime),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import cn.super12138.todo.R
|
||||
import cn.super12138.todo.ui.components.AnimatedExtendedFloatingActionButton
|
||||
|
||||
|
|
@ -33,7 +34,11 @@ fun TodoFAB(
|
|||
)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.action_add_task))
|
||||
Text(
|
||||
text = stringResource(R.string.action_add_task),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Clip
|
||||
)
|
||||
},
|
||||
expanded = expanded,
|
||||
elevation = elevation,
|
||||
|
|
|
|||
Loading…
Reference in a new issue