From 5d038932d902d543f8af8f8daad38bb48fdc3f58 Mon Sep 17 00:00:00 2001 From: xfy Date: Wed, 20 May 2026 01:28:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B9=B4=E8=A7=86=E5=9B=BE=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E6=A0=8F=E6=94=B9=E4=B8=BA=E5=86=9C=E5=8E=86=E5=B9=B2?= =?UTF-8?q?=E6=94=AF=E5=B9=B4=E4=BB=BD+=E3=80=8C=E4=BB=8A=E5=B9=B4?= =?UTF-8?q?=E3=80=8D=E6=8C=89=E9=92=AE=EF=BC=8C=E7=A7=BB=E9=99=A4=E7=AE=AD?= =?UTF-8?q?=E5=A4=B4=E5=AF=BC=E8=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - YearHeader 从 Row 改为 Column 布局 - 移除左右箭头年份切换,改为横向滑动翻页 - 添加农历干支+生肖年显示(如「丙午马年」) - 非当前年份时显示「今年」按钮,点击快速返回今年 - 同步移除 AppInfo.VERSION(已由动态版本号替代) Co-Authored-By: Claude Opus 4.7 (1M context) --- .../kotlin/plus/rua/project/AppInfo.kt | 1 - .../plus/rua/project/ui/CalendarMonthView.kt | 1 + .../plus/rua/project/ui/YearGridView.kt | 86 +++++++++++++------ 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/shared/src/commonMain/kotlin/plus/rua/project/AppInfo.kt b/shared/src/commonMain/kotlin/plus/rua/project/AppInfo.kt index 09f6e9f..506fac8 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/AppInfo.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/AppInfo.kt @@ -5,5 +5,4 @@ package plus.rua.project */ object AppInfo { const val NAME = "鸭鸭日历" - const val VERSION = "1.0" } diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt index 96d911b..10dfe56 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt @@ -225,6 +225,7 @@ fun CalendarMonthView( ) { YearHeader( year = viewModel.yearViewYear, + currentYear = today.year, onYearChange = { newYear -> val offset = newYear - viewModel.yearViewYear val targetPage = yearPagerState.currentPage + offset diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/YearGridView.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/YearGridView.kt index 4ab39b4..1ccc5db 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/YearGridView.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/YearGridView.kt @@ -1,6 +1,7 @@ package plus.rua.project.ui import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically @@ -8,23 +9,25 @@ import androidx.compose.animation.togetherWith import androidx.compose.foundation.Canvas import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText @@ -32,6 +35,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.tyme.lunar.LunarYear import kotlinx.datetime.DatePeriod import kotlinx.datetime.LocalDate import kotlinx.datetime.minus @@ -303,37 +307,28 @@ private fun generateMiniMonthDays(year: Int, month: Int): List { } /** - * 年视图标题栏,显示年份文字和左右导航箭头。 + * 年视图标题栏,左侧显示年份文字与农历干支年,右侧在非今年时显示「今年」按钮。 * - * 年份切换时文字有垂直滑动过渡动画,方向由新旧年份大小决定。 + * 年份切换时年份与农历年文字均有垂直滑动过渡动画。 * * @param year 当前年份 + * @param currentYear 今年年份 * @param onYearChange 年份切换回调 * @param modifier 外部布局修饰符 */ @Composable fun YearHeader( year: Int, + currentYear: Int, onYearChange: (Int) -> Unit, modifier: Modifier = Modifier ) { - Row( + Column( modifier = modifier .fillMaxWidth() - .padding(vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically + .padding(vertical = 8.dp, horizontal = 12.dp) ) { - Text( - text = "‹", - fontSize = 24.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier - .clip(CircleShape) - .clickable { onYearChange(year - 1) } - .padding(horizontal = 16.dp, vertical = 8.dp) - ) - Box(modifier = Modifier.weight(1f), contentAlignment = Alignment.Center) { + Row(verticalAlignment = Alignment.CenterVertically) { AnimatedContent( targetState = year, transitionSpec = { @@ -353,16 +348,51 @@ fun YearHeader( fontWeight = FontWeight.Bold ) } + Spacer(modifier = Modifier.weight(1f)) + val showThisYear = year != currentYear + val thisYearAlpha by animateFloatAsState( + targetValue = if (showThisYear) 1f else 0f, + animationSpec = tween(200) + ) + Text( + text = "今年", + color = MaterialTheme.colorScheme.primary, + fontSize = 14.sp, + modifier = Modifier + .graphicsLayer { alpha = thisYearAlpha } + .clip(RoundedCornerShape(12.dp)) + .clickable(enabled = showThisYear) { onYearChange(currentYear) } + .padding(horizontal = 10.dp, vertical = 4.dp) + ) + } + AnimatedContent( + targetState = year, + 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.padding(top = 4.dp) + ) { y -> + Text( + text = lunarYearLabel(y), + color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.6f), + style = MaterialTheme.typography.bodySmall + ) } - Text( - text = "›", - fontSize = 24.sp, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary, - modifier = Modifier - .clip(CircleShape) - .clickable { onYearChange(year + 1) } - .padding(horizontal = 16.dp, vertical = 8.dp) - ) } } + +/** + * 返回类似「丙午马年」的农历干支生肖年标签。 + */ +private fun lunarYearLabel(year: Int): String { + val sixtyCycle = LunarYear.fromYear(year).getSixtyCycle() + val ganZhi = sixtyCycle.getName() + val zodiac = sixtyCycle.getEarthBranch().getZodiac().getName() + return "${ganZhi}${zodiac}年" +}