为 Jetpack Compose 中的不可见项目预留 space

Reserve space for invisible items in Jetpack Compose

我正在尝试为我的新闻应用程序中的图像和文本字段制作动画。 我希望图标先出现,然后在几秒钟后出现文本。

我面临的问题是,当图标加载(首先)时,它位于绝对中心,当文本变得可见时,图标会稍微向上移动。我想停止先加载的图标的这种移动。

或者更准确地说,如何为屏幕上的不可见项目分配 space?

这是我的代码:

@Composable
fun SplashScreen(
    navController: NavController
){
    var imageVisibility by remember{
        mutableStateOf(false)
    }

    var textVisibility by remember{
        mutableStateOf(false)
    }

    LaunchedEffect(Unit){
        delay(1000)
        imageVisibility = true
        delay(5000)
        textVisibility = true
        delay(5000)
        navController.navigate(Destinations.HomeScreen.route)
    }


    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ){
        Column{
            AnimatedVisibility(
                visible = imageVisibility,
                enter = fadeIn(
                    TweenSpec(
                        durationMillis = 3000
                    )
                )
            ) {
                Image(
                    modifier = Modifier.fillMaxWidth(),
                    painter = painterResource(id = R.drawable.news_splash_screen),
                    contentDescription = "News Splash Screen"
                )
            }
            AnimatedVisibility(
                visible = textVisibility,
                enter = fadeIn(
                    TweenSpec(
                        durationMillis = 3000
                    )
                )
            ){
                Text(
                    modifier = Modifier.fillMaxWidth(),
                    text = "Read News Everyday",
                    textAlign = TextAlign.Center
                )
            }
        }
    }
}

使用 animateFloatAsStatealpha 设置动画,而不是 AnimatedVisibility 用于 Text

示例代码,

@Composable
fun SplashScreen(
    navHostController: NavController,
) {
    var imageVisibility by remember {
        mutableStateOf(false)
    }

    var textVisibility by remember {
        mutableStateOf(false)
    }

    LaunchedEffect(Unit) {
        delay(1000)
        imageVisibility = true
        delay(5000)
        textVisibility = true
        delay(5000)
        // navHostController.navigate("second")
    }
    val alpha: Float by animateFloatAsState(
        targetValue = if (textVisibility) {
            1f
        } else {
            0f
        },
        animationSpec = tween(
            durationMillis = 3000,
            easing = LinearEasing,
        ),
    )

    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Column {
            AnimatedVisibility(
                visible = imageVisibility,
                enter = fadeIn(
                    TweenSpec(
                        durationMillis = 3000
                    )
                )
            ) {
                Image(
                    modifier = Modifier.fillMaxWidth(),
                    painter = painterResource(id = R.drawable.ic_launcher_background),
                    contentDescription = "News Splash Screen"
                )
            }
            Text(
                modifier = Modifier
                    .fillMaxWidth()
                    .alpha(
                        alpha = alpha,
                    ),
                text = "Read News Everyday",
                textAlign = TextAlign.Center
            )
        }
    }
}