xfy 7250d08fb7 年视图标题固定 + 交叉淡入淡出 + 移除 fadeIn/fadeOut
年视图标题行从 HorizontalPager 内移到外部,左右滑动时标题不随 pager 滚动。
年份切换时标题文字用垂直滑动动画(与 MonthHeader 一致,移除 fadeIn/fadeOut)。
月/年视图左右滑动改为交叉淡入淡出,修复原实现中间全白的问题。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 14:14:46 +08:00

99 lines
3.4 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package plus.rua.project.ui
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
/**
* 月份标题栏,显示"年月"文字和 ISO 周号。
*
* @param year 年份
* @param month 月份1-12
* @param weekNumber 当前 ISO 周号
* @param showToday 是否显示「今天」按钮(当 selectedDate ≠ today 时)
* @param onToday 点击「今天」按钮跳转今天
* @param modifier 外部布局修饰符
*/
@Composable
fun MonthHeader(
year: Int,
month: Int,
weekNumber: Int,
showToday: Boolean,
onToday: (() -> Unit)? = null,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(vertical = 14.dp, horizontal = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
AnimatedContent(
targetState = Pair(year, month),
transitionSpec = {
if (targetState.second > initialState.second) {
slideInVertically(tween(250)) { -it } togetherWith
slideOutVertically(tween(250)) { it }
} else {
slideInVertically(tween(250)) { it } togetherWith
slideOutVertically(tween(250)) { -it }
}
}
) { (y, m) ->
Text(
text = "${y}${m}",
style = MaterialTheme.typography.titleLarge
)
}
Spacer(modifier = Modifier.width(6.dp))
AnimatedContent(
targetState = weekNumber,
transitionSpec = {
if (targetState > initialState) {
slideInVertically(tween(250)) { -it } togetherWith
slideOutVertically(tween(250)) { it }
} else {
slideInVertically(tween(250)) { it } togetherWith
slideOutVertically(tween(250)) { -it }
}
},
modifier = Modifier
) { week ->
Text(
text = "${week}",
style = MaterialTheme.typography.bodySmall
)
}
Spacer(modifier = Modifier.weight(1f))
if (showToday && onToday != null) {
Text(
text = "今天",
color = MaterialTheme.colorScheme.primary,
fontSize = 14.sp,
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.clickable(onClick = onToday)
.padding(horizontal = 10.dp, vertical = 4.dp)
)
}
}
}