From a731507b3b2b7f1a4adb6357dc091977dec9e1c2 Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 16 Jun 2026 14:19:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9C=88=E8=A7=86=E5=9B=BE=E5=B9=B4?= =?UTF-8?q?=E6=9C=88=E6=94=AF=E6=8C=81=E6=97=A5=E6=9C=9F=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MonthHeader 新增 onYearMonthClick 回调,点击年月文字打开日期选择器 - CalendarMonthView 集成 DatePickerDialog,选择日期后调用 selectDate - 复用现有 CalendarPager 动画,跨月跳转时自动平滑翻页 同时包含之前的改动: - 临时隐藏 SplashActivity 入口,改由 MainActivity 作为 LAUNCHER - benchmark build type 关闭 R8 混淆与资源压缩,保证 profile 可读性 --- app/build.gradle.kts | 6 +- app/src/main/AndroidManifest.xml | 16 +++-- .../plus/rua/project/ui/CalendarMonthView.kt | 58 ++++++++++++++++++- .../kotlin/plus/rua/project/ui/MonthHeader.kt | 8 ++- 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 915a6f6..b062a0c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -54,9 +54,11 @@ android { signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") // isDebuggable=false 使 macrobenchmark 在模拟器上稳定运行,且 Partial 编译模式可用。 - // 代价是生成的 baseline-prof.txt / startup-prof.txt 会包含 R8 混淆后的类名;功能上仍然有效。 - // 若需要可人工维护的可读 profile,请在真机上使用 debuggable build 或引入 Baseline Profile Gradle plugin。 + // 关闭混淆,保证生成的 baseline-prof.txt / startup-prof.txt 使用原始类名, + // 避免 R8 混淆签名导致 profile 匹配与维护风险。 isDebuggable = false + isMinifyEnabled = false + isShrinkResources = false } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 32abcd2..081ed34 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,20 +9,26 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.YaYa"> + + + android:theme="@style/Theme.YaYa.Splash" /> + + - - diff --git a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt index 24c7bf1..8e458e4 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt @@ -1,3 +1,5 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + package plus.rua.project.ui import androidx.compose.animation.AnimatedContent @@ -42,11 +44,16 @@ import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults +import androidx.compose.material3.DatePicker +import androidx.compose.material3.DatePickerDialog +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.rememberDatePickerState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -74,9 +81,12 @@ import kotlinx.coroutines.launch import kotlinx.datetime.LocalDate import kotlinx.datetime.Month import kotlinx.datetime.TimeZone +import kotlinx.datetime.atStartOfDayIn import kotlinx.datetime.number import kotlinx.datetime.plus +import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.todayIn +import kotlin.time.Instant import plus.rua.project.CalendarViewModel import plus.rua.project.ShiftKind import plus.rua.project.composeTraceBeginSection @@ -125,6 +135,7 @@ fun CalendarMonthView( var rowHeightPx by remember { mutableIntStateOf(0) } var screenWidthPx by remember { mutableIntStateOf(0) } var isMenuExpanded by remember { mutableStateOf(false) } + var showDatePicker by remember { mutableStateOf(false) } // 视图切换时自动关闭菜单 LaunchedEffect(isYearView) { @@ -214,7 +225,8 @@ fun CalendarMonthView( month = currentMonth, weekNumber = weekNumber, showToday = selectedDate != today, - onToday = onToday + onToday = onToday, + onYearMonthClick = { showDatePicker = true } ) WeekdayHeader( modifier = Modifier.fillMaxWidth().padding(bottom = ROW_PADDING_DP.dp) @@ -439,6 +451,34 @@ fun CalendarMonthView( } } } + + if (showDatePicker) { + val datePickerState = rememberDatePickerState( + initialSelectedDateMillis = selectedDate.toEpochMillis() + ) + DatePickerDialog( + onDismissRequest = { showDatePicker = false }, + confirmButton = { + TextButton( + onClick = { + datePickerState.selectedDateMillis?.let { millis -> + viewModel.selectDate(millis.toLocalDate()) + } + showDatePicker = false + } + ) { + Text("确定") + } + }, + dismissButton = { + TextButton(onClick = { showDatePicker = false }) { + Text("取消") + } + } + ) { + DatePicker(state = datePickerState) + } + } } } @@ -611,3 +651,19 @@ private fun MenuItem( ) } } + +/** + * 将 [LocalDate] 转换为 UTC 午夜的 epoch 毫秒。 + * + * 用于 DatePicker 初始选中值,与 [Long.toLocalDate] 成对使用。 + */ +private fun LocalDate.toEpochMillis(): Long = + this.atStartOfDayIn(TimeZone.UTC).toEpochMilliseconds() + +/** + * 将 epoch 毫秒转换为 UTC 日期的 [LocalDate]。 + * + * DatePicker 返回选中日期的 UTC 午夜毫秒,经此函数得到本地逻辑日期。 + */ +private fun Long.toLocalDate(): LocalDate = + Instant.fromEpochMilliseconds(this).toLocalDateTime(TimeZone.UTC).date diff --git a/core/src/main/kotlin/plus/rua/project/ui/MonthHeader.kt b/core/src/main/kotlin/plus/rua/project/ui/MonthHeader.kt index 7db15ff..a62fb3c 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/MonthHeader.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/MonthHeader.kt @@ -34,6 +34,7 @@ import androidx.compose.ui.unit.sp * @param weekNumber 当前 ISO 周号 * @param showToday 是否显示「今天」按钮(当 selectedDate ≠ today 时) * @param onToday 点击「今天」按钮跳转今天 + * @param onYearMonthClick 点击"年月"文字打开日期选择器 * @param modifier 外部布局修饰符 */ @Composable @@ -43,6 +44,7 @@ fun MonthHeader( weekNumber: Int, showToday: Boolean, onToday: (() -> Unit)? = null, + onYearMonthClick: () -> Unit = {}, modifier: Modifier = Modifier ) { Row( @@ -66,7 +68,11 @@ fun MonthHeader( Text( text = "${y}年${m}月", color = MaterialTheme.colorScheme.onBackground, - style = MaterialTheme.typography.titleLarge + style = MaterialTheme.typography.titleLarge, + modifier = Modifier + .clip(RoundedCornerShape(8.dp)) + .clickable(onClick = onYearMonthClick) + .padding(horizontal = 4.dp, vertical = 2.dp) ) } Spacer(modifier = Modifier.width(6.dp))