Fix first-frame flicker by deferring row height until measured

When rowHeightPx is 0 (first frame), use aspectRatio-based natural
height instead of collapsing to 0.dp, preventing a visible flash.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-14 15:27:26 +08:00
parent d7552e469f
commit edf8ea9851

View File

@ -53,6 +53,7 @@ fun CalendarMonthPage(
} }
var rowHeightPx by remember { mutableIntStateOf(0) } var rowHeightPx by remember { mutableIntStateOf(0) }
val rowMeasured = rowHeightPx > 0
Column(modifier = modifier) { Column(modifier = modifier) {
weeks.forEachIndexed { weekIndex, week -> weeks.forEachIndexed { weekIndex, week ->
@ -64,19 +65,27 @@ fun CalendarMonthPage(
else -> 1f else -> 1f
} }
val rowHeightDp = if (rowHeightPx > 0 && rowScale > 0.01f) { val rowHeightDp = if (rowMeasured && rowScale > 0.01f) {
with(density) { (rowHeightPx * rowScale).toDp() } with(density) { (rowHeightPx * rowScale).toDp() }
} else if (!rowMeasured) {
// First frame: let aspectRatio determine height naturally
null
} else { } else {
0.dp 0.dp
} }
if (rowHeightDp > 0.dp) { val shouldShow = rowHeightDp == null || rowHeightDp > 0.dp
if (shouldShow) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(rowHeightDp) .then(
if (rowHeightDp != null) Modifier.height(rowHeightDp)
else Modifier
)
.onSizeChanged { size -> .onSizeChanged { size ->
if (weekIndex == 0 && size.height > 0) { if (size.height > 0 && !rowMeasured) {
rowHeightPx = size.height rowHeightPx = size.height
} }
} }