refactor: 优化动画曲线 & 颜色变换动画性能
This commit is contained in:
parent
c33ed5d048
commit
eb7fa59302
3 changed files with 54 additions and 26 deletions
|
|
@ -38,7 +38,7 @@ android {
|
||||||
applicationId = "cn.super12138.todo"
|
applicationId = "cn.super12138.todo"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 985
|
versionCode = 986
|
||||||
versionName = "2.3.3"
|
versionName = "2.3.3"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
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
|
||||||
|
|
@ -85,6 +86,7 @@ fun SharedTransitionScope.TodoEditPage(
|
||||||
onNavigateUp = onNavigateUp
|
onNavigateUp = onNavigateUp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SharedTransitionScope.TodoEditorPage(
|
fun SharedTransitionScope.TodoEditorPage(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|
@ -210,8 +212,12 @@ fun SharedTransitionScope.TodoEditorPage(
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = isCustomCategory,
|
visible = isCustomCategory,
|
||||||
enter = fadeIn() + expandVertically(),
|
enter = fadeIn(MaterialTheme.motionScheme.defaultEffectsSpec()) + expandVertically(
|
||||||
exit = fadeOut() + shrinkVertically()
|
MaterialTheme.motionScheme.defaultEffectsSpec()
|
||||||
|
),
|
||||||
|
exit = fadeOut(MaterialTheme.motionScheme.defaultEffectsSpec()) + shrinkVertically(
|
||||||
|
MaterialTheme.motionScheme.defaultEffectsSpec()
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
TodoCategoryTextField(
|
TodoCategoryTextField(
|
||||||
value = uiState.categoryContent,
|
value = uiState.categoryContent,
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@ package cn.super12138.todo.ui.pages.tasks.components
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.ContentTransform
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.animation.expandIn
|
import androidx.compose.animation.expandIn
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.scaleIn
|
import androidx.compose.animation.scaleIn
|
||||||
import androidx.compose.animation.shrinkOut
|
import androidx.compose.animation.shrinkOut
|
||||||
import androidx.compose.animation.togetherWith
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
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
|
||||||
|
|
@ -22,9 +22,10 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.drawBehind
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
@ -34,7 +35,7 @@ import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.ui.TodoDefaults
|
import cn.super12138.todo.ui.TodoDefaults
|
||||||
import cn.super12138.todo.utils.VibrationUtils
|
import cn.super12138.todo.utils.VibrationUtils
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TodoTopAppBar(
|
fun TodoTopAppBar(
|
||||||
selectedTodoIds: List<Int>,
|
selectedTodoIds: List<Int>,
|
||||||
|
|
@ -44,8 +45,32 @@ fun TodoTopAppBar(
|
||||||
onDeleteSelectedTodo: () -> Unit,
|
onDeleteSelectedTodo: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
val navIconEnterTransition = fadeIn(
|
||||||
|
animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec()
|
||||||
|
) + expandIn(
|
||||||
|
animationSpec = MaterialTheme.motionScheme.defaultSpatialSpec(),
|
||||||
|
expandFrom = Alignment.CenterStart
|
||||||
|
)
|
||||||
|
val navIconExitTransition = fadeOut(
|
||||||
|
animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec()
|
||||||
|
) + shrinkOut(
|
||||||
|
animationSpec = MaterialTheme.motionScheme.defaultSpatialSpec(),
|
||||||
|
shrinkTowards = Alignment.CenterStart
|
||||||
|
)
|
||||||
|
val enterTransition = fadeIn(MaterialTheme.motionScheme.defaultEffectsSpec()) +
|
||||||
|
scaleIn(
|
||||||
|
animationSpec = MaterialTheme.motionScheme.defaultSpatialSpec(),
|
||||||
|
initialScale = 0.92f
|
||||||
|
)
|
||||||
|
val exitTransition = fadeOut(MaterialTheme.motionScheme.defaultEffectsSpec())
|
||||||
|
val titleTransition = ContentTransform(
|
||||||
|
targetContentEnter = enterTransition,
|
||||||
|
initialContentExit = exitTransition
|
||||||
|
)
|
||||||
|
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
val animatedTopAppBarColors by animateColorAsState(
|
val animatedContainerColor by animateColorAsState(
|
||||||
|
animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),
|
||||||
targetValue = if (selectedMode) {
|
targetValue = if (selectedMode) {
|
||||||
MaterialTheme.colorScheme.surfaceContainerHighest
|
MaterialTheme.colorScheme.surfaceContainerHighest
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -57,8 +82,8 @@ fun TodoTopAppBar(
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = selectedMode,
|
visible = selectedMode,
|
||||||
enter = fadeIn() + expandIn(expandFrom = Alignment.CenterStart),
|
enter = navIconEnterTransition,
|
||||||
exit = shrinkOut(shrinkTowards = Alignment.CenterStart) + fadeOut()
|
exit = navIconExitTransition
|
||||||
) {
|
) {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
|
@ -76,14 +101,7 @@ fun TodoTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = !selectedMode,
|
targetState = !selectedMode,
|
||||||
transitionSpec = {
|
transitionSpec = { titleTransition }
|
||||||
(
|
|
||||||
fadeIn(animationSpec = tween(100)) +
|
|
||||||
scaleIn(initialScale = 0.92f)
|
|
||||||
).togetherWith(
|
|
||||||
fadeOut(animationSpec = tween(100))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
if (it) {
|
if (it) {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -104,7 +122,11 @@ fun TodoTopAppBar(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
AnimatedVisibility(visible = selectedMode) {
|
AnimatedVisibility(
|
||||||
|
visible = selectedMode,
|
||||||
|
enter = enterTransition,
|
||||||
|
exit = exitTransition
|
||||||
|
) {
|
||||||
Row {
|
Row {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
|
@ -132,21 +154,21 @@ fun TodoTopAppBar(
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
colors = TopAppBarDefaults.topAppBarColors().copy(
|
colors = TopAppBarDefaults.topAppBarColors().copy(containerColor = Color.Transparent),
|
||||||
containerColor = animatedTopAppBarColors
|
modifier = modifier.drawBehind {
|
||||||
),
|
drawRect(animatedContainerColor)
|
||||||
modifier = modifier
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(locale = "zh-rCN", showBackground = true)
|
@Preview(locale = "zh-rCN", showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
private fun TodoTopAppBarPreview() {
|
private fun TodoTopAppBarPreview() {
|
||||||
var selectedMode by remember { mutableStateOf(false) }
|
val selectedMode = remember { mutableStateOf(false) }
|
||||||
TodoTopAppBar(
|
TodoTopAppBar(
|
||||||
selectedTodoIds = (1..10).toList(),
|
selectedTodoIds = (1..10).toList(),
|
||||||
selectedMode = selectedMode,
|
selectedMode = selectedMode.value,
|
||||||
onCancelSelect = { selectedMode = !selectedMode },
|
onCancelSelect = { selectedMode.value = !selectedMode.value },
|
||||||
onSelectAll = { },
|
onSelectAll = { },
|
||||||
onDeleteSelectedTodo = { }
|
onDeleteSelectedTodo = { }
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue