diff --git a/app/src/main/kotlin/plus/rua/project/AboutActivity.kt b/app/src/main/kotlin/plus/rua/project/AboutActivity.kt index 50a6839..ccb49b2 100644 --- a/app/src/main/kotlin/plus/rua/project/AboutActivity.kt +++ b/app/src/main/kotlin/plus/rua/project/AboutActivity.kt @@ -1,46 +1,19 @@ package plus.rua.project import android.content.Intent -import android.os.Build import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import plus.rua.project.ui.AboutScreen -class AboutActivity : ComponentActivity() { +class AboutActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() super.onCreate(savedInstanceState) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - overrideActivityTransition( - OVERRIDE_TRANSITION_OPEN, - R.anim.slide_in_right, - R.anim.slide_out_left - ) - overrideActivityTransition( - OVERRIDE_TRANSITION_CLOSE, - R.anim.slide_in_left, - R.anim.slide_out_right - ) - } - setContent { AboutScreen( - onBack = { - finish() - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) - } - }, + onBack = { finishWithSlideBack() }, onNavigateToLicenses = { - startActivity(Intent(this, LicensesActivity::class.java)) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left) - } + startActivityWithSlide(Intent(this, LicensesActivity::class.java)) } ) } diff --git a/app/src/main/kotlin/plus/rua/project/BaseActivity.kt b/app/src/main/kotlin/plus/rua/project/BaseActivity.kt new file mode 100644 index 0000000..b55df0f --- /dev/null +++ b/app/src/main/kotlin/plus/rua/project/BaseActivity.kt @@ -0,0 +1,60 @@ +package plus.rua.project + +import android.os.Build +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.enableEdgeToEdge +import androidx.annotation.AnimRes + +/** + * 提供 edge-to-edge 和 slide 转场动画的 Activity 基类。 + */ +abstract class BaseActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() + super.onCreate(savedInstanceState) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + overrideActivityTransition( + OVERRIDE_TRANSITION_OPEN, + R.anim.slide_in_right, + R.anim.slide_out_left + ) + overrideActivityTransition( + OVERRIDE_TRANSITION_CLOSE, + R.anim.slide_in_left, + R.anim.slide_out_right + ) + } + } + + /** + * 带 slide 返回动画的 finish。 + */ + protected fun finishWithSlideBack( + @AnimRes enterAnim: Int = R.anim.slide_in_left, + @AnimRes exitAnim: Int = R.anim.slide_out_right + ) { + finish() + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + @Suppress("DEPRECATION") + overridePendingTransition(enterAnim, exitAnim) + } + } + + /** + * 带 slide 进入动画的 startActivity。 + */ + protected fun startActivityWithSlide( + intent: android.content.Intent, + @AnimRes enterAnim: Int = R.anim.slide_in_right, + @AnimRes exitAnim: Int = R.anim.slide_out_left + ) { + startActivity(intent) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + @Suppress("DEPRECATION") + overridePendingTransition(enterAnim, exitAnim) + } + } +} diff --git a/app/src/main/kotlin/plus/rua/project/DateCheckerActivity.kt b/app/src/main/kotlin/plus/rua/project/DateCheckerActivity.kt index da23fe8..4251318 100644 --- a/app/src/main/kotlin/plus/rua/project/DateCheckerActivity.kt +++ b/app/src/main/kotlin/plus/rua/project/DateCheckerActivity.kt @@ -1,39 +1,16 @@ package plus.rua.project -import android.os.Build import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import plus.rua.project.ui.DateCheckerScreen -class DateCheckerActivity : ComponentActivity() { +class DateCheckerActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() super.onCreate(savedInstanceState) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - overrideActivityTransition( - OVERRIDE_TRANSITION_OPEN, - R.anim.slide_in_right, - R.anim.slide_out_left - ) - overrideActivityTransition( - OVERRIDE_TRANSITION_CLOSE, - R.anim.slide_in_left, - R.anim.slide_out_right - ) - } - setContent { DateCheckerScreen( - onBack = { - finish() - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) - } - } + onBack = { finishWithSlideBack() } ) } } diff --git a/app/src/main/kotlin/plus/rua/project/LicensesActivity.kt b/app/src/main/kotlin/plus/rua/project/LicensesActivity.kt index 4e25155..cafcaf8 100644 --- a/app/src/main/kotlin/plus/rua/project/LicensesActivity.kt +++ b/app/src/main/kotlin/plus/rua/project/LicensesActivity.kt @@ -1,39 +1,16 @@ package plus.rua.project -import android.os.Build import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import plus.rua.project.ui.LicensesScreen -class LicensesActivity : ComponentActivity() { +class LicensesActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() super.onCreate(savedInstanceState) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - overrideActivityTransition( - OVERRIDE_TRANSITION_OPEN, - R.anim.slide_in_right, - R.anim.slide_out_left - ) - overrideActivityTransition( - OVERRIDE_TRANSITION_CLOSE, - R.anim.slide_in_left, - R.anim.slide_out_right - ) - } - setContent { LicensesScreen( - onBack = { - finish() - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) - } - } + onBack = { finishWithSlideBack() } ) } } diff --git a/app/src/main/kotlin/plus/rua/project/MainActivity.kt b/app/src/main/kotlin/plus/rua/project/MainActivity.kt index fd0c63a..5851be4 100644 --- a/app/src/main/kotlin/plus/rua/project/MainActivity.kt +++ b/app/src/main/kotlin/plus/rua/project/MainActivity.kt @@ -1,34 +1,21 @@ package plus.rua.project import android.content.Intent -import android.os.Build import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge -import androidx.compose.runtime.Composable import plus.rua.project.ui.CalendarMonthView -class MainActivity : ComponentActivity() { +class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { CalendarMonthView( onNavigateToAbout = { - startActivity(Intent(this, AboutActivity::class.java)) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left) - } + startActivityWithSlide(Intent(this, AboutActivity::class.java)) }, onNavigateToTools = { - startActivity(Intent(this, ToolsActivity::class.java)) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left) - } + startActivityWithSlide(Intent(this, ToolsActivity::class.java)) } ) } diff --git a/app/src/main/kotlin/plus/rua/project/ToolsActivity.kt b/app/src/main/kotlin/plus/rua/project/ToolsActivity.kt index b35b370..6aac5c5 100644 --- a/app/src/main/kotlin/plus/rua/project/ToolsActivity.kt +++ b/app/src/main/kotlin/plus/rua/project/ToolsActivity.kt @@ -1,46 +1,19 @@ package plus.rua.project import android.content.Intent -import android.os.Build import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.enableEdgeToEdge import plus.rua.project.ui.ToolsScreen -class ToolsActivity : ComponentActivity() { +class ToolsActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() super.onCreate(savedInstanceState) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - overrideActivityTransition( - OVERRIDE_TRANSITION_OPEN, - R.anim.slide_in_right, - R.anim.slide_out_left - ) - overrideActivityTransition( - OVERRIDE_TRANSITION_CLOSE, - R.anim.slide_in_left, - R.anim.slide_out_right - ) - } - setContent { ToolsScreen( - onBack = { - finish() - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) - } - }, + onBack = { finishWithSlideBack() }, onNavigateToDateChecker = { - startActivity(Intent(this, DateCheckerActivity::class.java)) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { - @Suppress("DEPRECATION") - overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left) - } + startActivityWithSlide(Intent(this, DateCheckerActivity::class.java)) } ) } diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 99710cb..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 99710cb..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 2b7d06b..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 2b7d06b..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ 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 8d15520..656e815 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt @@ -66,6 +66,7 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.datetime.DatePeriod import kotlinx.datetime.LocalDate @@ -568,19 +569,21 @@ private fun BottomCardArea( label = "bottomCardSlide" ) - // P0-J: 延迟一帧显示 BottomCard,避免 AnimatedGif 和 lunar 计算阻塞首帧 - var frameCount by remember { mutableIntStateOf(0) } - androidx.compose.runtime.SideEffect { frameCount++ } - val shouldShow = frameCount >= 2 + // 延迟一帧显示 BottomCard,避免 AnimatedGif 和 lunar 计算阻塞首帧 + var hasLoaded by remember { mutableStateOf(false) } + LaunchedEffect(Unit) { + delay(32) + hasLoaded = true + } + val shouldShow = hasLoaded - val selectedDate by viewModel.selectedDate.collectAsState() - val isCollapsed by viewModel.isCollapsed.collectAsState() - val shiftKind = viewModel.shiftKindAt(selectedDate) + val uiState by viewModel.uiState.collectAsState() + val shiftKind = viewModel.shiftKindAt(uiState.selectedDate) if (shouldShow) { BottomCard( - isCollapsed = isCollapsed, - selectedDate = selectedDate, + isCollapsed = uiState.isCollapsed, + selectedDate = uiState.selectedDate, today = today, shiftKind = shiftKind, onDrag = { delta -> viewModel.onDrag(delta) },