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,
|
||||
modifier = modifier.sharedBounds(
|
||||
sharedContentState = rememberSharedContentState(key = "${Constants.KEY_TODO_ITEM_TRANSITION}_${toDo.id}"),
|
||||
animatedVisibilityScope = LocalNavAnimatedContentScope.current
|
||||
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||
resizeMode = SharedTransitionScope.ResizeMode.RemeasureToBounds
|
||||
),
|
||||
onSave = onSave,
|
||||
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.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.zIndex
|
||||
import androidx.navigation3.ui.LocalNavAnimatedContentScope
|
||||
import cn.super12138.todo.R
|
||||
import cn.super12138.todo.constants.Constants
|
||||
|
|
@ -142,7 +143,8 @@ fun SharedTransitionScope.TasksPage(
|
|||
modifier = Modifier
|
||||
.sharedBounds(
|
||||
sharedContentState = rememberSharedContentState(key = "${Constants.KEY_TODO_ITEM_TRANSITION}_${task.id}"),
|
||||
animatedVisibilityScope = LocalNavAnimatedContentScope.current
|
||||
animatedVisibilityScope = LocalNavAnimatedContentScope.current,
|
||||
resizeMode = SharedTransitionScope.ResizeMode.RemeasureToBounds
|
||||
)
|
||||
.animateItem(
|
||||
fadeInSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue