修复折叠态切换年视图:先展开再切换 + AnimatedContent 尺寸瞬切

折叠态下 toggleYearView 不再直接 return,而是先动画展开回月视图再进入年视图;
MonthHeader 的 AnimatedContent 添加 SizeTransform(snap()) 避免内容切换时尺寸动画;
清理未使用的 import。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-18 18:20:22 +08:00
parent 40c34f0606
commit 780a5e70dd
3 changed files with 12 additions and 6 deletions

View File

@ -112,9 +112,15 @@ class CalendarViewModel(
* 当前视图被直接移除动画只作用在目标视图的 scale/alpha * 当前视图被直接移除动画只作用在目标视图的 scale/alpha
*/ */
fun toggleYearView() { fun toggleYearView() {
if (isCollapsed) return
yearViewJob?.cancel() yearViewJob?.cancel()
yearViewJob = coroutineScope.launch { yearViewJob = coroutineScope.launch {
// 折叠态先展开回月视图,再切换年视图
if (isCollapsed) {
_collapseAnimatable.animateTo(
0f, spring(dampingRatio = 0.8f, stiffness = 400f)
)
isCollapsed = false
}
if (isYearView) { if (isYearView) {
// 年 → 月:先启动动画(年视图开始淡出),等一帧后翻转 isYearView月视图开始组合 // 年 → 月:先启动动画(年视图开始淡出),等一帧后翻转 isYearView月视图开始组合
composeTraceBeginSection("YearView→MonthView") composeTraceBeginSection("YearView→MonthView")

View File

@ -36,7 +36,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.withFrameNanos
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.snapshotFlow

View File

@ -1,7 +1,9 @@
package plus.rua.project.ui package plus.rua.project.ui
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
@ -16,12 +18,11 @@ import androidx.compose.foundation.shape.RoundedCornerShape
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
import androidx.compose.runtime.getValue
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.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.runtime.getValue
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -59,7 +60,7 @@ fun MonthHeader(
} else { } else {
slideInVertically(tween(250)) { it } togetherWith slideInVertically(tween(250)) { it } togetherWith
slideOutVertically(tween(250)) { -it } slideOutVertically(tween(250)) { -it }
} } using SizeTransform { _, _ -> snap() }
} }
) { (y, m) -> ) { (y, m) ->
Text( Text(
@ -77,7 +78,7 @@ fun MonthHeader(
} else { } else {
slideInVertically(tween(250)) { it } togetherWith slideInVertically(tween(250)) { it } togetherWith
slideOutVertically(tween(250)) { -it } slideOutVertically(tween(250)) { -it }
} } using SizeTransform { _, _ -> snap() }
}, },
modifier = Modifier modifier = Modifier
) { week -> ) { week ->