diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7df196f..32abcd2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,15 +10,19 @@ android:supportsRtl="true" android:theme="@style/Theme.YaYa"> + android:theme="@style/Theme.YaYa.Splash"> + + diff --git a/app/src/main/kotlin/plus/rua/project/MainActivity.kt b/app/src/main/kotlin/plus/rua/project/MainActivity.kt index 6ea86af..f9a24a4 100644 --- a/app/src/main/kotlin/plus/rua/project/MainActivity.kt +++ b/app/src/main/kotlin/plus/rua/project/MainActivity.kt @@ -4,13 +4,11 @@ import android.content.Intent import android.os.Bundle import androidx.activity.compose.ReportDrawn import androidx.activity.compose.setContent -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import plus.rua.project.ui.CalendarMonthView import plus.rua.project.ui.theme.YaYaTheme class MainActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { - installSplashScreen() super.onCreate(savedInstanceState) setContent { diff --git a/app/src/main/kotlin/plus/rua/project/SplashActivity.kt b/app/src/main/kotlin/plus/rua/project/SplashActivity.kt new file mode 100644 index 0000000..0042805 --- /dev/null +++ b/app/src/main/kotlin/plus/rua/project/SplashActivity.kt @@ -0,0 +1,43 @@ +package plus.rua.project + +import android.content.Intent +import android.os.Bundle +import androidx.activity.compose.setContent +import androidx.compose.ui.res.painterResource +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import plus.rua.project.ui.SplashScreen +import plus.rua.project.ui.theme.YaYaTheme + +private const val SPLASH_DELAY_MS = 400L + +/** + * 启动页 Activity。 + * + * 显示品牌启动图 400ms 后跳转到 [MainActivity],并 finish 自身。 + */ +class SplashActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContent { + YaYaTheme { + SplashScreen( + iconPainter = painterResource(R.mipmap.ic_launcher), + ) + } + } + + lifecycleScope.launch { + delay(SPLASH_DELAY_MS) + navigateToMain() + } + } + + private fun navigateToMain() { + if (isFinishing) return + startActivityWithSlide(Intent(this, MainActivity::class.java)) + finish() + } +} diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 6138c74..58abbfb 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -2,8 +2,15 @@ + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e498332..2297d58 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -5,10 +5,15 @@ + + diff --git a/core/src/main/kotlin/plus/rua/project/ui/SplashScreen.kt b/core/src/main/kotlin/plus/rua/project/ui/SplashScreen.kt new file mode 100644 index 0000000..89932c7 --- /dev/null +++ b/core/src/main/kotlin/plus/rua/project/ui/SplashScreen.kt @@ -0,0 +1,64 @@ +package plus.rua.project.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.statusBars +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import plus.rua.project.shared.R as CoreR + +private val SplashIconSize = 80.dp + +/** + * 品牌启动页 UI。 + * + * 背景图铺满全屏,Light/Dark 资源由 Android 根据配置自动选择。 + * app icon 水平居中,其垂直中心位于状态栏下方可用区域高度的约 25% 处。 + * 图片仅用于装饰,因此 contentDescription 为 null。 + * + * @param iconPainter app icon 的 Painter + * @param modifier 外部传入的 Modifier + */ +@Composable +fun SplashScreen( + iconPainter: Painter, + modifier: Modifier = Modifier, +) { + val configuration = LocalConfiguration.current + val density = LocalDensity.current + val screenHeightDp = configuration.screenHeightDp.dp + val statusBarHeight = with(density) { WindowInsets.statusBars.getTop(this).toDp() } + val availableHeight = screenHeightDp - statusBarHeight + val iconTopPadding = statusBarHeight + (availableHeight * 0.25f) - (SplashIconSize / 2) + + Box( + modifier = modifier.fillMaxSize(), + ) { + Image( + painter = painterResource(CoreR.drawable.launch_bg), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier.fillMaxSize(), + ) + + Image( + painter = iconPainter, + contentDescription = null, + modifier = Modifier + .align(Alignment.TopCenter) + .padding(top = iconTopPadding.coerceAtLeast(statusBarHeight)) + .size(SplashIconSize), + ) + } +}