feat: 年视图标题栏改为农历干支年份+「今年」按钮,移除箭头导航
- YearHeader 从 Row 改为 Column 布局 - 移除左右箭头年份切换,改为横向滑动翻页 - 添加农历干支+生肖年显示(如「丙午马年」) - 非当前年份时显示「今年」按钮,点击快速返回今年 - 同步移除 AppInfo.VERSION(已由动态版本号替代) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
841a186e0f
commit
5d038932d9
@ -5,5 +5,4 @@ package plus.rua.project
|
|||||||
*/
|
*/
|
||||||
object AppInfo {
|
object AppInfo {
|
||||||
const val NAME = "鸭鸭日历"
|
const val NAME = "鸭鸭日历"
|
||||||
const val VERSION = "1.0"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,6 +225,7 @@ fun CalendarMonthView(
|
|||||||
) {
|
) {
|
||||||
YearHeader(
|
YearHeader(
|
||||||
year = viewModel.yearViewYear,
|
year = viewModel.yearViewYear,
|
||||||
|
currentYear = today.year,
|
||||||
onYearChange = { newYear ->
|
onYearChange = { newYear ->
|
||||||
val offset = newYear - viewModel.yearViewYear
|
val offset = newYear - viewModel.yearViewYear
|
||||||
val targetPage = yearPagerState.currentPage + offset
|
val targetPage = yearPagerState.currentPage + offset
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package plus.rua.project.ui
|
package plus.rua.project.ui
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.slideInVertically
|
import androidx.compose.animation.slideInVertically
|
||||||
import androidx.compose.animation.slideOutVertically
|
import androidx.compose.animation.slideOutVertically
|
||||||
@ -8,23 +9,25 @@ import androidx.compose.animation.togetherWith
|
|||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
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.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
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.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.drawText
|
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.text.rememberTextMeasurer
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.tyme.lunar.LunarYear
|
||||||
import kotlinx.datetime.DatePeriod
|
import kotlinx.datetime.DatePeriod
|
||||||
import kotlinx.datetime.LocalDate
|
import kotlinx.datetime.LocalDate
|
||||||
import kotlinx.datetime.minus
|
import kotlinx.datetime.minus
|
||||||
@ -303,37 +307,28 @@ private fun generateMiniMonthDays(year: Int, month: Int): List<MiniDayData> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 年视图标题栏,显示年份文字和左右导航箭头。
|
* 年视图标题栏,左侧显示年份文字与农历干支年,右侧在非今年时显示「今年」按钮。
|
||||||
*
|
*
|
||||||
* 年份切换时文字有垂直滑动过渡动画,方向由新旧年份大小决定。
|
* 年份切换时年份与农历年文字均有垂直滑动过渡动画。
|
||||||
*
|
*
|
||||||
* @param year 当前年份
|
* @param year 当前年份
|
||||||
|
* @param currentYear 今年年份
|
||||||
* @param onYearChange 年份切换回调
|
* @param onYearChange 年份切换回调
|
||||||
* @param modifier 外部布局修饰符
|
* @param modifier 外部布局修饰符
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun YearHeader(
|
fun YearHeader(
|
||||||
year: Int,
|
year: Int,
|
||||||
|
currentYear: Int,
|
||||||
onYearChange: (Int) -> Unit,
|
onYearChange: (Int) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
Row(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 8.dp),
|
.padding(vertical = 8.dp, horizontal = 12.dp)
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
) {
|
||||||
Text(
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
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) {
|
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = year,
|
targetState = year,
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
@ -353,16 +348,51 @@ fun YearHeader(
|
|||||||
fontWeight = FontWeight.Bold
|
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(
|
||||||
text = "›",
|
text = "今年",
|
||||||
fontSize = 24.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
fontSize = 14.sp,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(CircleShape)
|
.graphicsLayer { alpha = thisYearAlpha }
|
||||||
.clickable { onYearChange(year + 1) }
|
.clip(RoundedCornerShape(12.dp))
|
||||||
.padding(horizontal = 16.dp, vertical = 8.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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回类似「丙午马年」的农历干支生肖年标签。
|
||||||
|
*/
|
||||||
|
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}年"
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user