diff --git a/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt b/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt index e2c342d..0930b69 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt @@ -59,7 +59,8 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) { // 拖拽超过 50% 时自动折叠到周视图,否则回弹到月视图 fun onDragEnd() { coroutineScope.launch { - if (_collapseAnimatable.value > 0.5f) { + val current = _collapseAnimatable.value + if (current > 0.5f) { _collapseAnimatable.animateTo( targetValue = 1f, animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f) @@ -85,7 +86,8 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) { // 下拉超过 50% 时自动展开到月视图,否则回弹到周视图 fun onExpandDragEnd() { coroutineScope.launch { - if (_collapseAnimatable.value < 0.5f) { + val current = _collapseAnimatable.value + if (current < 0.5f) { _collapseAnimatable.animateTo( targetValue = 0f, animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f) diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt index 61e7c27..12111fb 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt @@ -41,8 +41,12 @@ fun BottomCard( if (viewModel.isCollapsed) { // 折叠状态:下拉恢复到月视图 detectVerticalDragGestures( - onDragEnd = { viewModel.onExpandDragEnd() }, - onDragCancel = { viewModel.onExpandDragEnd() } + onDragEnd = { + viewModel.onExpandDragEnd() + }, + onDragCancel = { + viewModel.onExpandDragEnd() + } ) { _, dragAmount -> val delta = -dragAmount / dragRange viewModel.onExpandDrag(delta) @@ -50,8 +54,12 @@ fun BottomCard( } else { // 展开状态:上拉折叠到周视图 detectVerticalDragGestures( - onDragEnd = { viewModel.onDragEnd() }, - onDragCancel = { viewModel.onDragEnd() } + onDragEnd = { + viewModel.onDragEnd() + }, + onDragCancel = { + viewModel.onDragEnd() + } ) { _, dragAmount -> val delta = -dragAmount / dragRange viewModel.onDrag(delta) diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthPage.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthPage.kt index 1b58061..7d59351 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthPage.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthPage.kt @@ -19,8 +19,6 @@ import kotlinx.datetime.LocalDate import kotlinx.datetime.minus import kotlinx.datetime.plus -private const val TAG = "CalMonthPage" - /** * 月度日历网格页面,支持折叠动画。 * @@ -59,11 +57,8 @@ fun CalendarMonthPage( val totalHeightDp = if (rowHeightPx > 0) { val p = collapseProgress val totalPx = H * (1 + (effectiveWeeks - 1) * (1f - p)) - println("[$TAG] year=$year month=$month rowH=$rowHeightPx H=$H effWeeks=$effectiveWeeks " + - "weeks.size=${weeks.size} p=$p totalPx=$totalPx selWeek=$selectedWeekIndex") with(density) { totalPx.toDp() } } else { - println("[$TAG] year=$year month=$month rowH=0 (not yet measured)") null } @@ -98,7 +93,8 @@ fun CalendarMonthPage( } with(density) { yPx.toDp() } } else if (rowHeightPx > 0) { - with(density) { (weekIndex * H).toDp() } + val yPx = weekIndex * H + with(density) { yPx.toDp() } } else { 0.dp } diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt index 4b0ef33..986f352 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt @@ -32,7 +32,6 @@ import plus.rua.project.CalendarViewModel private const val START_PAGE = Int.MAX_VALUE / 2 private const val ROW_PADDING_DP = 4 -private const val TAG = "CalMonthView" /** * 日历主界面,包含月/周视图切换和折叠动画。 @@ -68,21 +67,23 @@ fun CalendarMonthView( val rowPaddingPx = with(density) { ROW_PADDING_DP.dp.toPx() }.toInt() // 滑动偏移插值行数 - // 始终以 settledPage 为锚点,currentPage - settledPage 确定方向(-1/0/+1), - // abs(offsetFraction) 为过渡进度。 - // 这样在 currentPage 跳变前后,方向和进度都是连续的: - // 跳变前: sp=8月, cp=8月, diff=0, offsetFraction>0 → 目标9月, fraction 0→0.5 - // 跳变后: sp=8月, cp=9月, diff=+1 → 目标9月, fraction 0.5→0 + // 以 currentPage 为基准页,offsetFraction 表示基准页与可视区域左边缘的偏移: + // offsetFraction > 0:基准页偏右,可视区域露出下一页(page+1) + // offsetFraction < 0:基准页偏左,可视区域露出上一页(page-1) + // 过渡进度 = abs(offsetFraction),目标页 = page ± 1。 + // 当 currentPage 跳变(如从 Jul 跳到 Aug),基准页行数也随之跳变, + // 但 abs(offsetFraction) 同时从 ~0.5 降到 ~0.5(连续),所以插值结果连续: + // 跳变前: cp=Jul(5行), off=+0.49 → base=5, target=Aug(6), lerp(5,6,0.49)=5.49 + // 跳变后: cp=Aug(6行), off=-0.47 → base=6, target=Jul(5), lerp(6,5,0.47)=5.47 ← 连续! val offsetFraction by remember { derivedStateOf { pagerState.currentPageOffsetFraction } } val interpolatedWeeks = if (abs(offsetFraction) > 0.01f) { - val sp = pagerState.settledPage - val diff = pagerState.currentPage - sp // -1, 0, or +1 - val targetPage = if (diff != 0) sp + diff else sp + if (offsetFraction > 0) 1 else -1 - val baseWeeks = calculateWeeksCountForPage(sp, today) + val cp = pagerState.currentPage + val baseWeeks = calculateWeeksCountForPage(cp, today) + val targetPage = cp + if (offsetFraction > 0) 1 else -1 val targetWeeks = calculateWeeksCountForPage(targetPage, today) lerp(baseWeeks.toFloat(), targetWeeks.toFloat(), abs(offsetFraction)) } else { - currentWeeksCount.toFloat() + calculateWeeksCountForPage(pagerState.currentPage, today).toFloat() } // 预估行高:DayCell aspectRatio=1,宽度 = (screenWidth - horizontalPadding) / 7 @@ -111,12 +112,6 @@ fun CalendarMonthView( val calendarAreaHeightPx = headerHeightPx + gridHeightPx + rowPaddingPx val cardHeightPx = if (screenHeightPx > 0 && calendarAreaHeightPx > 0) screenHeightPx - calendarAreaHeightPx else 0 - println("[$TAG] p=$p rowH=$rowHeightPx estRowH=$estimatedRowHeightPx effRowH=$effectiveRowHeightPx " + - "headerH=$headerHeightPx gridH=$gridHeightPx calAreaH=$calendarAreaHeightPx " + - "screenH=$screenHeightPx cardH=$cardHeightPx " + - "currentWeeks=$currentWeeksCount interpolatedWeeks=$interpolatedWeeks effectiveWeeks=$effectiveWeeks " + - "offsetFraction=$offsetFraction currentPage=${pagerState.currentPage} settledPage=${pagerState.settledPage}") - // 当 rowHeightPx 已知时,用计算的高度约束 pager;否则让 pager 自由扩展以测量行高 val pagerModifier = if (rowHeightPx > 0 && gridHeightPx > 0) { Modifier