Add debug logging and fix gridHeightPx derivedStateOf state tracking
gridHeightPx changed from derivedStateOf to direct computation because derivedStateOf cannot track non-State local variable changes, causing gridHeightPx to not update when rowHeightPx transitions from 0 to measured value. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
ddc852a667
commit
c74de5f151
@ -47,12 +47,14 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) {
|
||||
val currentMonth: Int get() = selectedDate.month.number
|
||||
|
||||
fun selectDate(date: LocalDate) {
|
||||
println("CalendarViewModel: selectDate $date (was $selectedDate)")
|
||||
selectedDate = date
|
||||
}
|
||||
|
||||
fun onDrag(delta: Float) {
|
||||
coroutineScope.launch {
|
||||
val new = (_collapseAnimatable.value + delta).coerceIn(0f, 1f)
|
||||
println("CalendarViewModel: onDrag delta=$delta, progress=${_collapseAnimatable.value} -> $new")
|
||||
_collapseAnimatable.snapTo(new)
|
||||
}
|
||||
}
|
||||
@ -61,17 +63,20 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) {
|
||||
fun onDragEnd() {
|
||||
coroutineScope.launch {
|
||||
val current = _collapseAnimatable.value
|
||||
println("CalendarViewModel: onDragEnd current=$current, threshold=$COLLAPSE_THRESHOLD")
|
||||
if (current > COLLAPSE_THRESHOLD) {
|
||||
_collapseAnimatable.animateTo(
|
||||
targetValue = 1f,
|
||||
animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f)
|
||||
)
|
||||
isCollapsed = true
|
||||
println("CalendarViewModel: collapsed=true")
|
||||
} else {
|
||||
_collapseAnimatable.animateTo(
|
||||
targetValue = 0f,
|
||||
animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f)
|
||||
)
|
||||
println("CalendarViewModel: snapped back to 0f")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,6 +85,7 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) {
|
||||
fun onExpandDrag(delta: Float) {
|
||||
coroutineScope.launch {
|
||||
val new = (_collapseAnimatable.value + delta).coerceIn(0f, 1f)
|
||||
println("CalendarViewModel: onExpandDrag delta=$delta, progress=${_collapseAnimatable.value} -> $new")
|
||||
_collapseAnimatable.snapTo(new)
|
||||
}
|
||||
}
|
||||
@ -88,17 +94,20 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) {
|
||||
fun onExpandDragEnd() {
|
||||
coroutineScope.launch {
|
||||
val current = _collapseAnimatable.value
|
||||
println("CalendarViewModel: onExpandDragEnd current=$current, threshold=$COLLAPSE_THRESHOLD")
|
||||
if (current < COLLAPSE_THRESHOLD) {
|
||||
_collapseAnimatable.animateTo(
|
||||
targetValue = 0f,
|
||||
animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f)
|
||||
)
|
||||
isCollapsed = false
|
||||
println("CalendarViewModel: expanded=false")
|
||||
} else {
|
||||
_collapseAnimatable.animateTo(
|
||||
targetValue = 1f,
|
||||
animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f)
|
||||
)
|
||||
println("CalendarViewModel: snapped back to 1f")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ fun BottomCard(
|
||||
) {
|
||||
val density = LocalDensity.current
|
||||
val dragRange = with(density) { DRAG_RANGE_DP.dp.toPx() }
|
||||
println("BottomCard: isCollapsed=${viewModel.isCollapsed}, dragRange=$dragRange, progress=${viewModel.collapseProgress}")
|
||||
|
||||
Surface(
|
||||
modifier = modifier
|
||||
|
||||
@ -115,7 +115,10 @@ fun CalendarMonthPage(
|
||||
.then(
|
||||
if (weekIndex == 0 && rowHeightPx == 0) {
|
||||
Modifier.onSizeChanged { size ->
|
||||
if (size.height > 0) onRowHeightMeasured?.invoke(size.height)
|
||||
if (size.height > 0) {
|
||||
println("CalendarMonthPage: measured rowHeight=${size.height}px, reporting to parent")
|
||||
onRowHeightMeasured?.invoke(size.height)
|
||||
}
|
||||
}
|
||||
} else Modifier
|
||||
)
|
||||
|
||||
@ -31,6 +31,8 @@ import kotlin.math.abs
|
||||
import kotlin.time.Clock
|
||||
import plus.rua.project.CalendarViewModel
|
||||
|
||||
private const val TAG = "CalendarMonthView"
|
||||
|
||||
/**
|
||||
* 日历主界面,包含月/周视图切换和折叠动画。
|
||||
*
|
||||
@ -59,8 +61,10 @@ fun CalendarMonthView(
|
||||
val pagerState = rememberPagerState(initialPage = START_PAGE, pageCount = { Int.MAX_VALUE })
|
||||
|
||||
val p = viewModel.collapseProgress
|
||||
println("$TAG: collapseProgress=$p, isCollapsed=${viewModel.isCollapsed}")
|
||||
val headerHeightPx = monthHeaderHeightPx + weekdayHeaderHeightPx
|
||||
val rowPaddingPx = with(density) { ROW_PADDING_DP.dp.toPx() }.toInt()
|
||||
println("$TAG: headerHeightPx=$headerHeightPx (month=$monthHeaderHeightPx, weekday=$weekdayHeaderHeightPx), rowPaddingPx=$rowPaddingPx")
|
||||
|
||||
val interpolatedWeeks by remember {
|
||||
derivedStateOf {
|
||||
@ -85,27 +89,28 @@ fun CalendarMonthView(
|
||||
(cellWidth + rowPadding).toInt()
|
||||
} else 0
|
||||
|
||||
println("$TAG: screenWidthPx=$screenWidthPx, screenHeightPx=$screenHeightPx, estimatedRowHeightPx=$estimatedRowHeightPx, measuredRowHeightPx=$rowHeightPx")
|
||||
|
||||
val effectiveRowHeightPx = if (rowHeightPx > 0) rowHeightPx else estimatedRowHeightPx
|
||||
|
||||
// 折叠时网格高度公式(与 CalendarMonthPage 一致):
|
||||
// gridH = rowH × (1 + (weeks-1) × (1-p))
|
||||
val effectiveWeeks = interpolatedWeeks
|
||||
|
||||
val gridHeightPx by remember {
|
||||
derivedStateOf {
|
||||
if (effectiveRowHeightPx > 0) {
|
||||
val rowH = effectiveRowHeightPx.toFloat()
|
||||
if (p > OFFSET_FRACTION_THRESHOLD) {
|
||||
(rowH * (1 + (effectiveWeeks - 1) * (1f - p))).toInt()
|
||||
} else {
|
||||
(rowH * effectiveWeeks).toInt()
|
||||
}
|
||||
} else 0
|
||||
// gridHeightPx 必须直接计算而非 derivedStateOf,因为 effectiveRowHeightPx 依赖 rowHeightPx state,
|
||||
// derivedStateOf 无法追踪非 State 的局部变量变化,导致 rowHeightPx 从 0 变为测量值时 gridHeightPx 不更新
|
||||
val gridHeightPx = if (effectiveRowHeightPx > 0) {
|
||||
val rowH = effectiveRowHeightPx.toFloat()
|
||||
if (p > OFFSET_FRACTION_THRESHOLD) {
|
||||
(rowH * (1 + (effectiveWeeks - 1) * (1f - p))).toInt()
|
||||
} else {
|
||||
(rowH * effectiveWeeks).toInt()
|
||||
}
|
||||
}
|
||||
} else 0
|
||||
|
||||
val calendarAreaHeightPx = headerHeightPx + gridHeightPx + rowPaddingPx
|
||||
val cardHeightPx = if (screenHeightPx > 0 && calendarAreaHeightPx > 0) screenHeightPx - calendarAreaHeightPx else 0
|
||||
println("$TAG: effectiveRowHeightPx=$effectiveRowHeightPx, effectiveWeeks=$effectiveWeeks, gridHeightPx=$gridHeightPx, calendarAreaHeightPx=$calendarAreaHeightPx, cardHeightPx=$cardHeightPx")
|
||||
|
||||
// 当 rowHeightPx 已知时,用计算的高度约束 pager;否则让 pager 自由扩展以测量行高
|
||||
val pagerModifier = if (rowHeightPx > 0 && gridHeightPx > 0) {
|
||||
@ -141,6 +146,7 @@ fun CalendarMonthView(
|
||||
)
|
||||
// 完全折叠且无动画时显示 WeekPager,否则显示 CalendarPager(含下拉恢复过程)
|
||||
if (viewModel.isCollapsed && viewModel.collapseProgress >= 1f) {
|
||||
println("$TAG: Showing WeekPager (isCollapsed=true, progress=${viewModel.collapseProgress})")
|
||||
WeekPager(
|
||||
selectedDate = viewModel.selectedDate,
|
||||
today = today,
|
||||
@ -152,6 +158,7 @@ fun CalendarMonthView(
|
||||
}
|
||||
)
|
||||
} else {
|
||||
println("$TAG: Showing CalendarPager (isCollapsed=${viewModel.isCollapsed}, progress=${viewModel.collapseProgress})")
|
||||
CalendarPager(
|
||||
selectedDate = viewModel.selectedDate,
|
||||
today = today,
|
||||
@ -174,6 +181,7 @@ fun CalendarMonthView(
|
||||
}
|
||||
|
||||
if (cardHeightPx > 0) {
|
||||
println("$TAG: BottomCard height=${with(density) { cardHeightPx.toDp() }}")
|
||||
BottomCard(
|
||||
viewModel = viewModel,
|
||||
modifier = Modifier
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user