You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中使用自定义Composable作为启动页?

实现Composable Logo作为启动页(基于SplashScreen API + Navigation Compose)

问题背景

已编写Logo.kt作为自定义启动页Composable组件,当前项目使用SplashScreen API配置启动页,希望替换默认图标为该Logo组件,同时避免延迟跳转导致的白屏问题,且项目基于Navigation Compose实现页面导航。


解决方案步骤

1. 调整SplashScreen主题配置

修改themes.xml,移除默认图标配置,将主题背景设置为Logo渐变的起始色,避免切换时的视觉断层:

<style name="Theme.CustomSplashScreenTheme" parent="Theme.SplashScreen">
    <!-- 与Logo渐变起始色保持一致,避免切换突兀 -->
    <item name="windowSplashScreenBackground">@color/splash_start_color</item>
    <item name="windowSplashScreenAnimationDuration">600</item>
    <item name="postSplashScreenTheme">@style/Theme.BaeCallingApp</item>
    <!-- 移除默认图标配置,使用自定义Composable替代 -->
</style>

同时在colors.xml中添加对应颜色:

<color name="splash_start_color">#0A1478</color>

2. 优化Logo组件的字体加载逻辑

避免Composable重组时重复加载字体,使用remember缓存字体资源:

@Composable
fun Logo(modifier: Modifier = Modifier) {
    val gradient = Brush.verticalGradient(
        colors = listOf(
            Color(0xFF0A1478),
            Color(0xFFBEC8FF)
        )
    )
    val context = LocalContext.current
    // 用remember缓存字体,提升性能
    val customTypeFace = remember {
        context.resources.getFont(R.font.marckscript_regular)
    }

    Canvas(
        modifier = modifier
            .fillMaxSize()
            .background(gradient)
    ) {
        val padding = 20
        val path = Path().apply {
            moveTo(x = padding.toFloat() * 6, y = center.y)
            lineTo(x = size.width - padding * 6, y = center.y)
        }

        this.drawContext.canvas.nativeCanvas.apply {
            drawTextOnPath(
                "BAE Calling App",
                path.asAndroidPath(),
                0f,
                0f,
                Paint().apply {
                    this.color = android.graphics.Color.WHITE
                    this.textSize = 120f
                    this.textAlign = Paint.Align.CENTER
                    this.typeface = customTypeFace
                }
            )
        }
    }
}

@Preview(showBackground = true)
@Composable
fun LogoPreview() {
    BaeCallingAppTheme {
        Logo()
    }
}

3. 修改MainActivity逻辑,绑定SplashScreen与Logo组件

利用SplashScreen API的setContent方法直接加载自定义Composable,同时通过ViewModel状态控制启动页显示时长:

class MainActivity : ComponentActivity() {

    @Inject
    lateinit var splashViewModel: SplashViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        installSplashScreen().apply {
            // 将Logo组件设置为SplashScreen的内容
            setContent {
                BaeCallingAppTheme {
                    Logo()
                }
            }
            // 加载过程中保持启动页,完成后自动切换
            setKeepOnScreenCondition {
                splashViewModel.isLoading.value
            }
        }
        // SplashScreen消失后加载导航页面
        setContent {
            BaeCallingAppTheme {
                val screen by splashViewModel.startDestination.collectAsStateWithLifecycle()
                setUpNavController(
                    controller = rememberNavController(),
                    startDestination = screen
                )
            }
        }
    }
}

核心说明

  • 使用SplashScreen API的setContent方法是官方支持的自定义启动页方式,可在系统启动页窗口直接展示Composable内容,避免白屏问题;
  • 通过ViewModel的isLoading状态控制启动页显示时长,无需手动延迟跳转;
  • 缓存字体资源符合Composable最佳实践,避免重复加载导致的性能损耗。

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:45:52