Add pull-down gesture to expand from collapsed week view back to month view

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-14 17:02:44 +08:00
parent 1c232762b1
commit c1e0484cba
3 changed files with 46 additions and 8 deletions

View File

@ -74,6 +74,32 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) {
}
}
// 折叠状态下下拉恢复delta 为负值(向下拖)推动 progress 向 0
fun onExpandDrag(delta: Float) {
coroutineScope.launch {
val new = (_collapseAnimatable.value + delta).coerceIn(0f, 1f)
_collapseAnimatable.snapTo(new)
}
}
// 下拉超过 50% 时自动展开到月视图,否则回弹到周视图
fun onExpandDragEnd() {
coroutineScope.launch {
if (_collapseAnimatable.value < 0.5f) {
_collapseAnimatable.animateTo(
targetValue = 0f,
animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f)
)
isCollapsed = false
} else {
_collapseAnimatable.animateTo(
targetValue = 1f,
animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f)
)
}
}
}
/**
* 计算给定日期的 ISO 8601 周号
*

View File

@ -38,13 +38,24 @@ fun BottomCard(
modifier = modifier
.fillMaxWidth()
.pointerInput(viewModel.isCollapsed) {
if (viewModel.isCollapsed) return@pointerInput
detectVerticalDragGestures(
onDragEnd = { viewModel.onDragEnd() },
onDragCancel = { viewModel.onDragEnd() }
) { _, dragAmount ->
val delta = -dragAmount / dragRange
viewModel.onDrag(delta)
if (viewModel.isCollapsed) {
// 折叠状态:下拉恢复到月视图
detectVerticalDragGestures(
onDragEnd = { viewModel.onExpandDragEnd() },
onDragCancel = { viewModel.onExpandDragEnd() }
) { _, dragAmount ->
val delta = -dragAmount / dragRange
viewModel.onExpandDrag(delta)
}
} else {
// 展开状态:上拉折叠到周视图
detectVerticalDragGestures(
onDragEnd = { viewModel.onDragEnd() },
onDragCancel = { viewModel.onDragEnd() }
) { _, dragAmount ->
val delta = -dragAmount / dragRange
viewModel.onDrag(delta)
}
}
},
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),

View File

@ -106,7 +106,8 @@ fun CalendarMonthView(
weekdayHeaderHeightPx = size.height
}
)
if (viewModel.isCollapsed) {
// 完全折叠且无动画时显示 WeekPager否则显示 CalendarPager含下拉恢复过程
if (viewModel.isCollapsed && viewModel.collapseProgress >= 1f) {
WeekPager(
selectedDate = viewModel.selectedDate,
today = today,