feat(splash): use SplashScreen API with custom background
This commit is contained in:
parent
fab3c2d763
commit
8204ae15cf
@ -10,19 +10,15 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.YaYa">
|
android:theme="@style/Theme.YaYa">
|
||||||
<activity
|
<activity
|
||||||
android:name=".SplashActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/Theme.YaYa.Splash">
|
android:theme="@style/Theme.YaYa.Starting">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:exported="true" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".AboutActivity"
|
android:name=".AboutActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,11 +3,7 @@
|
|||||||
<style name="Theme.YaYa" parent="@android:style/Theme.Material.NoActionBar" />
|
<style name="Theme.YaYa" parent="@android:style/Theme.Material.NoActionBar" />
|
||||||
|
|
||||||
<style name="Theme.YaYa.Starting" parent="Theme.SplashScreen">
|
<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>
|
<item name="postSplashScreenTheme">@style/Theme.YaYa</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.YaYa.Splash" parent="@android:style/Theme.Material.NoActionBar">
|
|
||||||
<item name="android:windowBackground">@color/splash_background</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -5,15 +5,10 @@
|
|||||||
<!--
|
<!--
|
||||||
启动主题:用于 MAIN/LAUNCHER Activity。
|
启动主题:用于 MAIN/LAUNCHER Activity。
|
||||||
继承 Theme.SplashScreen,保证 Android 12 以下也能获得一致的启动窗口行为。
|
继承 Theme.SplashScreen,保证 Android 12 以下也能获得一致的启动窗口行为。
|
||||||
windowSplashScreenBackground 使用 Material 3 静态基准色,作为动态颜色不可用时
|
windowSplashScreenBackground 使用启动背景图作为窗口背景。
|
||||||
的 fallback,以减少启动窗口与 Compose 首帧之间的色差闪烁。
|
|
||||||
-->
|
-->
|
||||||
<style name="Theme.YaYa.Starting" parent="Theme.SplashScreen">
|
<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>
|
<item name="postSplashScreenTheme">@style/Theme.YaYa</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.YaYa.Splash" parent="@android:style/Theme.Material.Light.NoActionBar">
|
|
||||||
<item name="android:windowBackground">@color/splash_background</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@ -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),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user