Change collapse animation to shrink non-selected rows instead of overlaying

Non-selected rows now compress their height proportionally with
collapse progress, replacing the previous overlay-based approach.
Remove KDoc that described the old overlay behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-14 15:50:22 +08:00
parent a44ef44b42
commit 2fb36168a3

View File

@ -3,6 +3,7 @@ package plus.rua.project.ui
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -21,20 +22,6 @@ import kotlinx.datetime.LocalDate
import kotlinx.datetime.minus import kotlinx.datetime.minus
import kotlinx.datetime.plus import kotlinx.datetime.plus
/**
* 月度日历网格页6×7 布局支持折叠动画
*
* 折叠时选中行保持原高并向上移动覆盖其他行其他行保持原位不动
* 选中行通过 offset + zIndex 实现覆盖效果
*
* @param year 年份
* @param month 月份1-12
* @param selectedDate 当前选中日期
* @param today 今天的日期
* @param onDateClick 日期点击回调
* @param collapseProgress 折叠进度0f=展开61f=折叠仅选中行可见
* @param modifier 外部布局修饰符
*/
@Composable @Composable
fun CalendarMonthPage( fun CalendarMonthPage(
year: Int, year: Int,
@ -56,9 +43,10 @@ fun CalendarMonthPage(
} }
var rowHeightPx by remember { mutableIntStateOf(0) } var rowHeightPx by remember { mutableIntStateOf(0) }
val rowMeasured = rowHeightPx > 0
// 选中行上移距离 = 上方行数 × 行高 × progress // 选中行上移距离 = 上方行数 × 行高 × progress
val selectedOffsetPx = if (rowHeightPx > 0) { val selectedOffsetPx = if (rowMeasured) {
-(selectedWeekIndex.toFloat() * rowHeightPx.toFloat() * collapseProgress) -(selectedWeekIndex.toFloat() * rowHeightPx.toFloat() * collapseProgress)
} else { } else {
0f 0f
@ -68,34 +56,55 @@ fun CalendarMonthPage(
Column(modifier = modifier.clipToBounds()) { Column(modifier = modifier.clipToBounds()) {
weeks.forEachIndexed { weekIndex, week -> weeks.forEachIndexed { weekIndex, week ->
val isSelected = weekIndex == selectedWeekIndex val isSelected = weekIndex == selectedWeekIndex
val isAboveSelected = weekIndex < selectedWeekIndex
val isBelowSelected = weekIndex > selectedWeekIndex
Row( // 非选中行高度跟手压缩
modifier = Modifier val rowScale = when {
.fillMaxWidth() isAboveSelected || isBelowSelected -> 1f - collapseProgress
.zIndex(if (isSelected) 1f else 0f) else -> 1f
.then( }
if (isSelected && rowHeightPx > 0) {
Modifier.offset(y = selectedOffsetDp) val rowHeightDp = if (rowMeasured && rowScale > 0.01f) {
} else { with(density) { (rowHeightPx.toFloat() * rowScale).toDp() }
Modifier } else if (!rowMeasured) {
} null
) } else {
.onSizeChanged { size -> 0.dp
if (size.height > 0 && rowHeightPx == 0) { }
rowHeightPx = size.height
val shouldShow = rowHeightDp == null || rowHeightDp > 0.dp
if (shouldShow) {
Row(
modifier = Modifier
.fillMaxWidth()
.zIndex(if (isSelected) 1f else 0f)
.then(
if (rowHeightDp != null) Modifier.height(rowHeightDp)
else Modifier
)
.then(
if (isSelected && rowMeasured) Modifier.offset(y = selectedOffsetDp)
else Modifier
)
.onSizeChanged { size ->
if (size.height > 0 && !rowMeasured) {
rowHeightPx = size.height
}
} }
.padding(vertical = 2.dp)
) {
week.forEach { dayData ->
DayCell(
date = dayData.date,
isCurrentMonth = dayData.isCurrentMonth,
isSelected = dayData.date == selectedDate,
isToday = dayData.date == today,
onClick = { onDateClick(dayData.date) },
modifier = Modifier.weight(1f)
)
} }
.padding(vertical = 2.dp)
) {
week.forEach { dayData ->
DayCell(
date = dayData.date,
isCurrentMonth = dayData.isCurrentMonth,
isSelected = dayData.date == selectedDate,
isToday = dayData.date == today,
onClick = { onDateClick(dayData.date) },
modifier = Modifier.weight(1f)
)
} }
} }
} }