feat: 法定假日背景添加波浪缩放动画
点击"显示调休"后,假日格子背景从左上到右下依次缩放弹出(每格延迟15ms), 关闭时反向缩放消失,使用 graphicsLayer 实现高性能动画。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
3c1a04580c
commit
6dffaf4c91
@ -253,7 +253,7 @@ private fun WeekRow(
|
|||||||
)
|
)
|
||||||
.padding(vertical = ROW_PADDING_DP.dp)
|
.padding(vertical = ROW_PADDING_DP.dp)
|
||||||
) {
|
) {
|
||||||
week.forEach { dayData ->
|
week.forEachIndexed { dayIndex, dayData ->
|
||||||
key(dayData.date) {
|
key(dayData.date) {
|
||||||
DayCell(
|
DayCell(
|
||||||
date = dayData.date,
|
date = dayData.date,
|
||||||
@ -263,6 +263,7 @@ private fun WeekRow(
|
|||||||
shiftKind = shiftKindAt(dayData.date),
|
shiftKind = shiftKindAt(dayData.date),
|
||||||
showLegalHoliday = showLegalHoliday,
|
showLegalHoliday = showLegalHoliday,
|
||||||
holidayEdgeInfo = holidayEdges[dayData.date],
|
holidayEdgeInfo = holidayEdges[dayData.date],
|
||||||
|
cellIndex = weekIndex * 7 + dayIndex,
|
||||||
onClick = { onDateClick(dayData.date) },
|
onClick = { onDateClick(dayData.date) },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
|
|||||||
@ -3,8 +3,11 @@ package plus.rua.project.ui
|
|||||||
import androidx.compose.animation.animateColor
|
import androidx.compose.animation.animateColor
|
||||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
import androidx.compose.animation.core.animateFloat
|
import androidx.compose.animation.core.animateFloat
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.core.updateTransition
|
import androidx.compose.animation.core.updateTransition
|
||||||
|
import androidx.compose.ui.graphics.TransformOrigin
|
||||||
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
@ -57,6 +60,7 @@ enum class DayCellState {
|
|||||||
* false(默认):排班放右上角,不显示法定调休背景。
|
* false(默认):排班放右上角,不显示法定调休背景。
|
||||||
* true:排班仍在右上角,法定假日以淡色背景显示("休"淡红,"班"淡蓝)。
|
* true:排班仍在右上角,法定假日以淡色背景显示("休"淡红,"班"淡蓝)。
|
||||||
* @param holidayEdgeInfo 假日在连续序列中的边缘状态,决定背景圆角。null 表示无假日。
|
* @param holidayEdgeInfo 假日在连续序列中的边缘状态,决定背景圆角。null 表示无假日。
|
||||||
|
* @param cellIndex 单元格在月网格中的线性索引(weekIndex*7+dayIndex),用于法定假日波浪动画延迟。
|
||||||
* @param onClick 点击回调
|
* @param onClick 点击回调
|
||||||
* @param modifier 外部布局修饰符
|
* @param modifier 外部布局修饰符
|
||||||
*/
|
*/
|
||||||
@ -69,6 +73,7 @@ fun DayCell(
|
|||||||
shiftKind: ShiftKind?,
|
shiftKind: ShiftKind?,
|
||||||
showLegalHoliday: Boolean,
|
showLegalHoliday: Boolean,
|
||||||
holidayEdgeInfo: HolidayEdgeInfo? = null,
|
holidayEdgeInfo: HolidayEdgeInfo? = null,
|
||||||
|
cellIndex: Int = 0,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
@ -84,6 +89,7 @@ fun DayCell(
|
|||||||
shiftKind = shiftKind,
|
shiftKind = shiftKind,
|
||||||
showLegalHoliday = showLegalHoliday,
|
showLegalHoliday = showLegalHoliday,
|
||||||
holidayEdgeInfo = holidayEdgeInfo,
|
holidayEdgeInfo = holidayEdgeInfo,
|
||||||
|
cellIndex = cellIndex,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
@ -105,6 +111,7 @@ fun DayCell(
|
|||||||
shiftKind = shiftKind,
|
shiftKind = shiftKind,
|
||||||
showLegalHoliday = showLegalHoliday,
|
showLegalHoliday = showLegalHoliday,
|
||||||
holidayEdgeInfo = holidayEdgeInfo,
|
holidayEdgeInfo = holidayEdgeInfo,
|
||||||
|
cellIndex = cellIndex,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
@ -122,6 +129,7 @@ private fun DayCellImpl(
|
|||||||
shiftKind: ShiftKind?,
|
shiftKind: ShiftKind?,
|
||||||
showLegalHoliday: Boolean,
|
showLegalHoliday: Boolean,
|
||||||
holidayEdgeInfo: HolidayEdgeInfo?,
|
holidayEdgeInfo: HolidayEdgeInfo?,
|
||||||
|
cellIndex: Int,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
modifier: Modifier,
|
modifier: Modifier,
|
||||||
interactionSource: MutableInteractionSource,
|
interactionSource: MutableInteractionSource,
|
||||||
@ -220,11 +228,21 @@ private fun DayCellImpl(
|
|||||||
else -> Color.Transparent
|
else -> Color.Transparent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val holidayScale by animateFloatAsState(
|
||||||
|
targetValue = if (showLegalHoliday && holidayBadge != null) 1f else 0f,
|
||||||
|
animationSpec = tween(
|
||||||
|
durationMillis = 200,
|
||||||
|
delayMillis = cellIndex * 15,
|
||||||
|
easing = FastOutSlowInEasing
|
||||||
|
),
|
||||||
|
label = "holidayScale"
|
||||||
|
)
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier.aspectRatio(1f)
|
modifier = modifier.aspectRatio(1f)
|
||||||
) {
|
) {
|
||||||
// 法定假日背景(最底层,与选中/今天状态叠加)
|
// 法定假日背景(最底层,与选中/今天状态叠加)
|
||||||
if (showLegalHoliday && holidayBadge != null) {
|
if (holidayScale > 0f) {
|
||||||
val holidayShape = when {
|
val holidayShape = when {
|
||||||
holidayEdgeInfo?.isStart == true && holidayEdgeInfo.isEnd -> RoundedCornerShape(8.dp)
|
holidayEdgeInfo?.isStart == true && holidayEdgeInfo.isEnd -> RoundedCornerShape(8.dp)
|
||||||
holidayEdgeInfo?.isStart == true -> RoundedCornerShape(topStart = 8.dp, bottomStart = 8.dp)
|
holidayEdgeInfo?.isStart == true -> RoundedCornerShape(topStart = 8.dp, bottomStart = 8.dp)
|
||||||
@ -235,6 +253,11 @@ private fun DayCellImpl(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(horizontal = 0.5.dp)
|
.padding(horizontal = 0.5.dp)
|
||||||
|
.graphicsLayer {
|
||||||
|
scaleX = holidayScale
|
||||||
|
scaleY = holidayScale
|
||||||
|
transformOrigin = TransformOrigin.Center
|
||||||
|
}
|
||||||
.background(holidayBgColor, holidayShape)
|
.background(holidayBgColor, holidayShape)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,6 +112,7 @@ fun WeekPager(
|
|||||||
isToday = date == today,
|
isToday = date == today,
|
||||||
shiftKind = shiftKindAt(date),
|
shiftKind = shiftKindAt(date),
|
||||||
showLegalHoliday = showLegalHoliday,
|
showLegalHoliday = showLegalHoliday,
|
||||||
|
cellIndex = dayOffset,
|
||||||
onClick = { onDateClick(date) },
|
onClick = { onDateClick(date) },
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user