feat(splash): add custom SplashActivity with background image
This commit is contained in:
parent
de329c2020
commit
21327d572b
@ -10,15 +10,19 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.YaYa">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".SplashActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.YaYa.Starting">
|
||||
android:theme="@style/Theme.YaYa.Splash">
|
||||
<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" />
|
||||
|
||||
@ -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 {
|
||||
|
||||
43
app/src/main/kotlin/plus/rua/project/SplashActivity.kt
Normal file
43
app/src/main/kotlin/plus/rua/project/SplashActivity.kt
Normal file
@ -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()
|
||||
}
|
||||
}
|
||||
@ -2,8 +2,15 @@
|
||||
<resources>
|
||||
<style name="Theme.YaYa" parent="@android:style/Theme.Material.NoActionBar" />
|
||||
|
||||
<!--
|
||||
启动主题:用于 MAIN/LAUNCHER Activity。
|
||||
-->
|
||||
<style name="Theme.YaYa.Starting" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@drawable/launch_bg</item>
|
||||
<item name="windowSplashScreenBackground">@color/splash_background</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>
|
||||
|
||||
@ -5,10 +5,15 @@
|
||||
<!--
|
||||
启动主题:用于 MAIN/LAUNCHER Activity。
|
||||
继承 Theme.SplashScreen,保证 Android 12 以下也能获得一致的启动窗口行为。
|
||||
windowSplashScreenBackground 使用启动背景图作为窗口背景。
|
||||
windowSplashScreenBackground 使用 Material 3 静态基准色,作为动态颜色不可用时
|
||||
的 fallback,以减少启动窗口与 Compose 首帧之间的色差闪烁。
|
||||
-->
|
||||
<style name="Theme.YaYa.Starting" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@drawable/launch_bg</item>
|
||||
<item name="windowSplashScreenBackground">@color/splash_background</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>
|
||||
|
||||
64
core/src/main/kotlin/plus/rua/project/ui/SplashScreen.kt
Normal file
64
core/src/main/kotlin/plus/rua/project/ui/SplashScreen.kt
Normal file
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user