refactor: 优化待办卡片共享元素转场动画
This commit is contained in:
parent
2fbb6fd38c
commit
bc9face5a1
3 changed files with 5 additions and 139 deletions
|
|
@ -73,7 +73,8 @@ fun SharedTransitionScope.TodoEditPage(
|
||||||
toDo = toDo,
|
toDo = toDo,
|
||||||
modifier = modifier.sharedBounds(
|
modifier = modifier.sharedBounds(
|
||||||
sharedContentState = rememberSharedContentState(key = "${Constants.KEY_TODO_ITEM_TRANSITION}_${toDo.id}"),
|
sharedContentState = rememberSharedContentState(key = "${Constants.KEY_TODO_ITEM_TRANSITION}_${toDo.id}"),
|
||||||
animatedVisibilityScope = LocalNavAnimatedContentScope.current
|
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||||
|
resizeMode = SharedTransitionScope.ResizeMode.RemeasureToBounds
|
||||||
),
|
),
|
||||||
onSave = onSave,
|
onSave = onSave,
|
||||||
onDelete = onDelete,
|
onDelete = onDelete,
|
||||||
|
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
package cn.super12138.todo.ui.pages.tasks
|
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.animation.expandVertically
|
|
||||||
import androidx.compose.animation.fadeIn
|
|
||||||
import androidx.compose.animation.fadeOut
|
|
||||||
import androidx.compose.animation.shrinkVertically
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.material3.CircularWavyProgressIndicator
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.ProgressIndicatorDefaults
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.StrokeCap
|
|
||||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
|
||||||
import androidx.compose.ui.semantics.contentDescription
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import cn.super12138.todo.R
|
|
||||||
import cn.super12138.todo.ui.TodoDefaults
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
|
||||||
@Composable
|
|
||||||
fun ProgressFragment(
|
|
||||||
totalTasks: Int,
|
|
||||||
completedTasks: Int,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
val thickStrokeWidth = with(LocalDensity.current) { TodoDefaults.trackThickness.toPx() }
|
|
||||||
val thickStroke = remember(thickStrokeWidth) {
|
|
||||||
Stroke(width = thickStrokeWidth, cap = StrokeCap.Round)
|
|
||||||
}
|
|
||||||
|
|
||||||
val remainTasks = totalTasks - completedTasks
|
|
||||||
val progress = if (totalTasks != 0) {
|
|
||||||
completedTasks / totalTasks.toFloat()
|
|
||||||
} else {
|
|
||||||
// 没有任务时
|
|
||||||
0f
|
|
||||||
}
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = modifier.padding(20.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
val animatedProgress by animateFloatAsState(
|
|
||||||
targetValue = progress,
|
|
||||||
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
|
|
||||||
)
|
|
||||||
|
|
||||||
CircularWavyProgressIndicator(
|
|
||||||
progress = { animatedProgress },
|
|
||||||
stroke = thickStroke,
|
|
||||||
trackStroke = thickStroke,
|
|
||||||
amplitude = { progress ->
|
|
||||||
if (progress <= 0.1f || progress >= 0.95f) {
|
|
||||||
0f
|
|
||||||
} else {
|
|
||||||
TodoDefaults.waveAmplitude
|
|
||||||
}
|
|
||||||
},
|
|
||||||
wavelength = TodoDefaults.waveLength,
|
|
||||||
waveSpeed = TodoDefaults.waveSpeed,
|
|
||||||
modifier = Modifier
|
|
||||||
.size(175.dp)
|
|
||||||
.clearAndSetSemantics {}
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
modifier = Modifier.clearAndSetSemantics {
|
|
||||||
contentDescription = if (totalTasks != 0) {
|
|
||||||
context.getString(
|
|
||||||
R.string.accessibility_progress_tasks,
|
|
||||||
totalTasks,
|
|
||||||
completedTasks,
|
|
||||||
remainTasks
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
context.getString(R.string.accessibility_progress_no_tasks)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = completedTasks.toString(),
|
|
||||||
style = MaterialTheme.typography.displaySmall.copy(
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.placeholder_divider),
|
|
||||||
style = MaterialTheme.typography.displayMedium.copy(
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = totalTasks.toString(),
|
|
||||||
style = MaterialTheme.typography.displayMedium.copy(
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
AnimatedVisibility(
|
|
||||||
visible = remainTasks != 0,
|
|
||||||
enter = fadeIn(MaterialTheme.motionScheme.fastSpatialSpec()) + expandVertically(
|
|
||||||
MaterialTheme.motionScheme.fastSpatialSpec()
|
|
||||||
),
|
|
||||||
exit = fadeOut(MaterialTheme.motionScheme.fastSpatialSpec()) + shrinkVertically(
|
|
||||||
MaterialTheme.motionScheme.fastSpatialSpec()
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.tip_remain_tasks, remainTasks),
|
|
||||||
style = MaterialTheme.typography.labelMedium,
|
|
||||||
modifier = Modifier.clearAndSetSemantics {}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -27,6 +27,7 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.zIndex
|
||||||
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||||
import cn.super12138.todo.R
|
import cn.super12138.todo.R
|
||||||
import cn.super12138.todo.constants.Constants
|
import cn.super12138.todo.constants.Constants
|
||||||
|
|
@ -142,7 +143,8 @@ fun SharedTransitionScope.TasksPage(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.sharedBounds(
|
.sharedBounds(
|
||||||
sharedContentState = rememberSharedContentState(key = "${Constants.KEY_TODO_ITEM_TRANSITION}_${task.id}"),
|
sharedContentState = rememberSharedContentState(key = "${Constants.KEY_TODO_ITEM_TRANSITION}_${task.id}"),
|
||||||
animatedVisibilityScope = LocalNavAnimatedContentScope.current
|
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||||
|
resizeMode = SharedTransitionScope.ResizeMode.RemeasureToBounds
|
||||||
)
|
)
|
||||||
.animateItem(
|
.animateItem(
|
||||||
fadeInSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),
|
fadeInSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue