fix: 恢复折叠动画 Phase 2 下方行偏移,移除 showWeekPager 切换

- 恢复 CalendarMonthPage 中 isBelow 行的 `- phase2 * belowRowsHeight`
  (2592a5f 误删导致展开时下方行原地淡入而非滑出)
- 移除 CalendarMonthView 的 showWeekPager + AnimatedContent 切换
  (完全折叠后下拉拖拽时只显示 WeekPager 单周,上下空白)
- 回退到始终显示 CalendarPager,由 CalendarMonthPage 处理折叠动画
- 添加详细动画调试日志(Page/WeekRow/View 三层)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-26 17:39:40 +08:00
parent 2592a5fa55
commit 20425e392c
2 changed files with 41 additions and 66 deletions

View File

@ -106,6 +106,17 @@ fun CalendarMonthPage(
val anchorIndex = remember(year, month, selectedDate) {
weeks.indexOfFirst { week -> week.any { it.date == selectedDate } }
}
// 全局动画参数日志(每次重组)
val pageFrameNs = System.nanoTime()
Log.d(
TAG_CMP,
"Page[$year-$month]: anchorIndex=$anchorIndex weeksSize=${weeks.size} " +
"phase1End=${if (anchorIndex > 0 && weeks.size > 1) anchorIndex.toFloat() / (weeks.size - 1) else 0f} " +
"effectiveWeeks=$effectiveWeeks rowHeightPx=$rowHeightPx " +
"collapseProgress=$collapseProgress frameNs=$pageFrameNs"
)
val totalHeightDp = if (rowHeightPx > 0) {
val h = rowHeightPx.toFloat()
val totalPx = h * (1 + (effectiveWeeks - 1) * (1f - collapseProgress))
@ -188,7 +199,7 @@ private fun WeekRow(
!hasAnchor -> weekIndex * h - collapseProgress * weeksSize * h
isAnchor -> anchorIndex * h * (1f - phase1)
isAbove -> weekIndex * h - phase1 * anchorIndex * h
isBelow -> weekIndex * h - phase1 * anchorIndex * h
isBelow -> weekIndex * h - phase1 * anchorIndex * h - phase2 * belowRowsHeight
else -> weekIndex * h
}
} else 0f
@ -201,9 +212,17 @@ private fun WeekRow(
else -> 1f
}
if (isAnchor || isBelow) {
Log.d(TAG_CMP, "WeekRow[$weekIndex]: isAnchor=$isAnchor isAbove=$isAbove isBelow=$isBelow phase1=$phase1 phase2=$phase2 yOffsetPx=$yOffsetPx rowAlpha=$rowAlpha collapseProgress=$collapseProgress")
}
val frameTimeNs = System.nanoTime()
Log.d(
TAG_CMP,
"WeekRow[$weekIndex]: " +
"isAnchor=$isAnchor isAbove=$isAbove isBelow=$isBelow " +
"phase1=$phase1 phase2=$phase2 phase1End=$phase1End " +
"belowRowsHeight=$belowRowsHeight rowHeightPx=$rowHeightPx " +
"yOffsetPx=$yOffsetPx rowAlpha=$rowAlpha " +
"collapseProgress=$collapseProgress " +
"frameNs=$frameTimeNs"
)
if (rowAlpha > 0.01f) {
Row(

View File

@ -48,6 +48,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
@ -69,7 +70,6 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.datetime.DatePeriod
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.datetime.number
@ -82,6 +82,7 @@ import plus.rua.project.composeTraceEndSection
import kotlin.math.abs
import kotlin.time.Clock
import androidx.lifecycle.viewmodel.compose.viewModel
import android.util.Log
/**
* 日历主界面包含月/周视图切换折叠动画和年视图共享元素转场
@ -118,6 +119,9 @@ fun CalendarMonthView(
animationSpec = spring(stiffness = Spring.StiffnessMedium),
label = "collapseProgress"
)
SideEffect {
Log.d("CalendarExpandAnim", "View: target=$collapseProgress animated=$animatedCollapseProgress isCollapsed=$isCollapsed")
}
val density = LocalDensity.current
val coroutineScope = rememberCoroutineScope()
@ -238,7 +242,6 @@ fun CalendarMonthView(
CalendarPagerArea(
selectedDate = selectedDate,
today = today,
isCollapsed = isCollapsed,
collapseProgress = animatedCollapseProgress,
showLegalHoliday = showLegalHoliday,
rowHeightPx = rowHeightPx,
@ -463,7 +466,6 @@ private fun MenuIcon(color: Color, modifier: Modifier = Modifier) {
private fun CalendarPagerArea(
selectedDate: LocalDate,
today: LocalDate,
isCollapsed: Boolean,
collapseProgress: Float,
showLegalHoliday: Boolean,
rowHeightPx: Int,
@ -520,66 +522,20 @@ private fun CalendarPagerArea(
modifier
}
// 延迟切换:等折叠 spring 动画完全稳定后再切到 WeekPager避免视觉跳跃
var showWeekPager by remember { mutableStateOf(false) }
LaunchedEffect(isCollapsed, collapseProgress) {
if (isCollapsed && collapseProgress >= 0.999f) {
delay(50)
showWeekPager = true
} else if (!isCollapsed) {
showWeekPager = false
}
}
AnimatedContent(
targetState = showWeekPager,
transitionSpec = { fadeIn(tween(80)) togetherWith fadeOut(tween(80)) },
label = "pager_switch",
CalendarPager(
selectedDate = selectedDate,
today = today,
onDateClick = onDateClick,
onMonthChanged = onMonthChanged,
collapseProgress = collapseProgress,
rowHeightPx = rowHeightPx,
effectiveWeeks = effectiveWeeks,
shiftKindAt = shiftKindAt,
showLegalHoliday = showLegalHoliday,
onRowHeightMeasured = onRowHeightMeasured,
pagerState = pagerState,
modifier = pagerModifier
) { useWeekPager ->
if (useWeekPager) {
WeekPager(
selectedDate = selectedDate,
today = today,
onDateClick = onDateClick,
onWeekChanged = { weekMonday ->
val weekSunday = weekMonday.plus(DatePeriod(days = 6))
val date = when {
today in weekMonday..weekSunday -> today
weekMonday.month != weekSunday.month -> {
if (weekMonday < selectedDate) {
@Suppress("DEPRECATION")
LocalDate(weekSunday.year, weekSunday.month.number, 1)
} else {
weekMonday
}
}
else -> weekMonday
}
onDateClick(date)
},
shiftKindAt = shiftKindAt,
showLegalHoliday = showLegalHoliday,
modifier = Modifier
)
} else {
CalendarPager(
selectedDate = selectedDate,
today = today,
onDateClick = onDateClick,
onMonthChanged = onMonthChanged,
collapseProgress = collapseProgress,
rowHeightPx = rowHeightPx,
effectiveWeeks = effectiveWeeks,
shiftKindAt = shiftKindAt,
showLegalHoliday = showLegalHoliday,
onRowHeightMeasured = onRowHeightMeasured,
pagerState = pagerState,
modifier = Modifier
)
}
}
)
}
@Composable