cleanup: 提取 Activity 基类、修复 Compose 状态、精简资源

A. 提取 Activity 共用代码:
- 新增 BaseActivity 基类,统一处理 enableEdgeToEdge 和 slide 转场动画
- 5 个子 Activity 从 ~212 行简化为 ~50 行,减少 150+ 行重复代码

B. 修复 Compose 状态问题:
- BottomCardArea: 移除对 selectedDate/isCollapsed 的独立 StateFlow 订阅,
  统一使用 uiState 聚合流
- 替换脆弱的 SideEffect 帧计数器为显式 LaunchedEffect + delay(32)

C. 资源精简:
- 删除 mipmap-mdpi 和 mipmap-hdpi 密度(现代设备已被覆盖)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xfy 2026-05-25 15:08:00 +08:00
parent 5bac114c16
commit dead12fdf4
11 changed files with 85 additions and 135 deletions

View File

@ -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))
}
)
}

View File

@ -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)
}
}
}

View File

@ -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() }
)
}
}

View File

@ -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() }
)
}
}

View File

@ -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))
}
)
}

View File

@ -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))
}
)
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -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) },