feat(splash): use SplashScreen API with custom background

This commit is contained in:
xfy 2026-06-16 12:27:12 +08:00
parent fab3c2d763
commit 8204ae15cf
5 changed files with 5 additions and 140 deletions

View File

@ -10,19 +10,15 @@
android:supportsRtl="true"
android:theme="@style/Theme.YaYa">
<activity
android:name=".SplashActivity"
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.YaYa.Splash">
android:theme="@style/Theme.YaYa.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true" />
<activity
android:name=".AboutActivity"
android:exported="false" />

View File

@ -1,45 +0,0 @@
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.shared.R as CoreR
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(
backgroundPainter = painterResource(CoreR.drawable.launch_bg),
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()
}
}

View File

@ -3,11 +3,7 @@
<style name="Theme.YaYa" parent="@android:style/Theme.Material.NoActionBar" />
<style name="Theme.YaYa.Starting" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splash_background</item>
<item name="windowSplashScreenBackground">@drawable/launch_bg</item>
<item name="postSplashScreenTheme">@style/Theme.YaYa</item>
</style>
<style name="Theme.YaYa.Splash" parent="@android:style/Theme.Material.NoActionBar">
<item name="android:windowBackground">@color/splash_background</item>
</style>
</resources>

View File

@ -5,15 +5,10 @@
<!--
启动主题:用于 MAIN/LAUNCHER Activity。
继承 Theme.SplashScreen保证 Android 12 以下也能获得一致的启动窗口行为。
windowSplashScreenBackground 使用 Material 3 静态基准色,作为动态颜色不可用时
的 fallback以减少启动窗口与 Compose 首帧之间的色差闪烁。
windowSplashScreenBackground 使用启动背景图作为窗口背景。
-->
<style name="Theme.YaYa.Starting" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splash_background</item>
<item name="windowSplashScreenBackground">@drawable/launch_bg</item>
<item name="postSplashScreenTheme">@style/Theme.YaYa</item>
</style>
<style name="Theme.YaYa.Splash" parent="@android:style/Theme.Material.Light.NoActionBar">
<item name="android:windowBackground">@color/splash_background</item>
</style>
</resources>

View File

@ -1,77 +0,0 @@
package plus.rua.project.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
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.Color
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.unit.dp
private const val DarkOverlayAlpha = 0.4f
private val SplashIconSize = 80.dp
/**
* 品牌启动页 UI
*
* 背景图铺满全屏暗色模式下叠加半透明黑色蒙层降低亮度
* app icon 水平居中其垂直中心位于状态栏下方可用区域高度的约 25%
* 图片仅用于装饰因此 contentDescription null
*
* @param backgroundPainter 启动背景图的 Painter
* @param iconPainter app icon Painter
* @param modifier 外部传入的 Modifier
*/
@Composable
fun SplashScreen(
backgroundPainter: Painter,
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)
val isDark = isSystemInDarkTheme()
Box(
modifier = modifier.fillMaxSize(),
) {
Image(
painter = backgroundPainter,
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize(),
)
if (isDark) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = DarkOverlayAlpha)),
)
}
Image(
painter = iconPainter,
contentDescription = null,
modifier = Modifier
.align(Alignment.TopCenter)
.padding(top = iconTopPadding.coerceAtLeast(statusBarHeight))
.size(SplashIconSize),
)
}
}