节日改为只在当天显示,休/班改为右上角角标
之前法定假期的「春节休」之类文本占据了整段假期,把假期里出现 的节气(雨水、惊蛰等)和其他节日全部挤掉。现在拆成两条线: - 主标注:按 农历节日 → 节气当天 → 公历节日 → 农历日期 的 优先级,仅在节日/节气当天展示节日名。 - 右上角角标:单独读取法定假期标志,调休「休」为 error 色, 调休「班」为 primary 色;非当月时整体降低不透明度。 DayCell 外层多包一层 Box 承载 aspectRatio,原内层保留圆形裁 剪与涟漪;角标放在外层 TopEnd,避免被 CircleShape 裁掉。
This commit is contained in:
parent
889a54db0e
commit
c28eb8d0e5
@ -9,7 +9,9 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@ -25,6 +27,7 @@ import androidx.compose.ui.semantics.contentDescription
|
|||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -113,18 +116,18 @@ fun DayCell(
|
|||||||
|
|
||||||
data class DayAnnotation(val text: String, val isHighlight: Boolean)
|
data class DayAnnotation(val text: String, val isHighlight: Boolean)
|
||||||
|
|
||||||
|
val holidayBadge = remember(date) {
|
||||||
|
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
||||||
|
val solarDay = SolarDay.fromYmd(date.year, date.monthNumber, date.day)
|
||||||
|
solarDay.getLegalHoliday()?.let { if (it.isWork()) "班" else "休" }
|
||||||
|
}
|
||||||
|
|
||||||
val annotation = remember(date) {
|
val annotation = remember(date) {
|
||||||
|
@Suppress("DEPRECATION") // monthNumber 无替代 API
|
||||||
val solarDay = SolarDay.fromYmd(date.year, date.monthNumber, date.day)
|
val solarDay = SolarDay.fromYmd(date.year, date.monthNumber, date.day)
|
||||||
val lunarDay = solarDay.getLunarDay()
|
val lunarDay = solarDay.getLunarDay()
|
||||||
|
|
||||||
// 法定假日优先
|
// 农历传统节日(仅当天)
|
||||||
val legalHoliday = solarDay.getLegalHoliday()
|
|
||||||
if (legalHoliday != null) {
|
|
||||||
val suffix = if (legalHoliday.isWork()) "班" else "休"
|
|
||||||
return@remember DayAnnotation("${legalHoliday.getName()}$suffix", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 农历传统节日
|
|
||||||
val lunarFestival = lunarDay.getFestival()
|
val lunarFestival = lunarDay.getFestival()
|
||||||
if (lunarFestival != null) {
|
if (lunarFestival != null) {
|
||||||
return@remember DayAnnotation(lunarFestival.getName(), true)
|
return@remember DayAnnotation(lunarFestival.getName(), true)
|
||||||
@ -136,7 +139,7 @@ fun DayCell(
|
|||||||
return@remember DayAnnotation(termDay.getSolarTerm().getName(), true)
|
return@remember DayAnnotation(termDay.getSolarTerm().getName(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 公历节日
|
// 公历节日(仅当天)
|
||||||
val solarFestival = solarDay.getFestival()
|
val solarFestival = solarDay.getFestival()
|
||||||
if (solarFestival != null) {
|
if (solarFestival != null) {
|
||||||
return@remember DayAnnotation(solarFestival.getName(), true)
|
return@remember DayAnnotation(solarFestival.getName(), true)
|
||||||
@ -176,52 +179,75 @@ fun DayCell(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val holidayBadgeColor = when (holidayBadge) {
|
||||||
|
"休" -> MaterialTheme.colorScheme.error
|
||||||
|
"班" -> MaterialTheme.colorScheme.primary
|
||||||
|
else -> Color.Transparent
|
||||||
|
}
|
||||||
|
val holidayBadgeAlpha = if (isCurrentMonth) 1f else 0.38f
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier.aspectRatio(1f)
|
||||||
.aspectRatio(1f)
|
|
||||||
.semantics {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
contentDescription = "${date.year}年${date.monthNumber}月${date.day}日"
|
|
||||||
}
|
|
||||||
.clip(CircleShape)
|
|
||||||
.drawBehind {
|
|
||||||
if (revealProgress > 0f) {
|
|
||||||
val maxRadius = size.minDimension / 2f
|
|
||||||
drawCircle(
|
|
||||||
color = selectedColor,
|
|
||||||
radius = revealProgress * maxRadius,
|
|
||||||
center = Offset(size.width / 2f, size.height / 2f)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (borderAlpha > 0f) {
|
|
||||||
drawCircle(
|
|
||||||
color = todayBorderColor.copy(alpha = borderAlpha.coerceAtMost(1f)),
|
|
||||||
radius = size.minDimension / 2f,
|
|
||||||
center = Offset(size.width / 2f, size.height / 2f),
|
|
||||||
style = Stroke(width = borderAlpha.coerceAtMost(1.5f) * 1.5.dp.toPx())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.clickable(onClick = onClick),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Box(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.semantics {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
contentDescription = "${date.year}年${date.monthNumber}月${date.day}日"
|
||||||
|
}
|
||||||
|
.clip(CircleShape)
|
||||||
|
.drawBehind {
|
||||||
|
if (revealProgress > 0f) {
|
||||||
|
val maxRadius = size.minDimension / 2f
|
||||||
|
drawCircle(
|
||||||
|
color = selectedColor,
|
||||||
|
radius = revealProgress * maxRadius,
|
||||||
|
center = Offset(size.width / 2f, size.height / 2f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (borderAlpha > 0f) {
|
||||||
|
drawCircle(
|
||||||
|
color = todayBorderColor.copy(alpha = borderAlpha.coerceAtMost(1f)),
|
||||||
|
radius = size.minDimension / 2f,
|
||||||
|
center = Offset(size.width / 2f, size.height / 2f),
|
||||||
|
style = Stroke(width = borderAlpha.coerceAtMost(1.5f) * 1.5.dp.toPx())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.clickable(onClick = onClick),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = date.day.toString(),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = contentColor,
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = annotation.text,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = lunarColor,
|
||||||
|
fontSize = 7.sp,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Clip,
|
||||||
|
lineHeight = 9.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (holidayBadge != null) {
|
||||||
Text(
|
Text(
|
||||||
text = date.day.toString(),
|
text = holidayBadge,
|
||||||
textAlign = TextAlign.Center,
|
color = holidayBadgeColor.copy(alpha = holidayBadgeAlpha),
|
||||||
color = contentColor,
|
fontSize = 9.sp,
|
||||||
style = MaterialTheme.typography.bodyMedium
|
fontWeight = FontWeight.Bold,
|
||||||
)
|
lineHeight = 9.sp,
|
||||||
Text(
|
modifier = Modifier
|
||||||
text = annotation.text,
|
.align(Alignment.TopEnd)
|
||||||
textAlign = TextAlign.Center,
|
.padding(top = 2.dp, end = 4.dp)
|
||||||
color = lunarColor,
|
|
||||||
fontSize = 7.sp,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Clip,
|
|
||||||
lineHeight = 9.sp
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user