plzy의 개발 블로그

[Compose] compose로 splash 만들기 본문

Android

[Compose] compose로 splash 만들기

plzyhappy 2022. 6. 22. 09:34

Compose를 사용하기 전에는 Splash Theme를 사용하거나, startActivity 등 사용해서 만들면 됐었다.

하지만 Compose에서는 조금 방법이 다르다.

바로 Navigation을 사용해야한다.

먼저 splash로 사용할 화면과, splash 후에 나올 화면을 NavHost에 정의해 준다.

startDestination 에서 어느 화면이 가장 먼저 실행될 것인지 명시해준다.

@Composable
fun BosoDiaryApp() {

    // navigation 설정

    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = Screen.Splash.route

    ) {
        composable(route = Screen.Splash.route) {
            AnimationSplashScreen(navController)
        }
        composable(route = Screen.Login.route) {
            LoginScreen(navController)
        }
    }

}

이 함수는 MainActivity에서 사용한다.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SecretDiaryTheme {
               BosoDiaryApp()
            }
        }
    }
}

SplashScreen에서 LaunchedEffect안에서 navigate로 화면을 이동하는것을 볼 수 있다.
LaunchedEffect는 side-Effect로 비동기로 처리된다.

기존의 Runnable, Corutine으로 splash화면을 구현했던것처럼 비동기로 구현하는 거다.

@Composable
fun SplashScreenContent() {

    val density = LocalDensity.current
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        AnimatedVisibility(
            visible = true,
            enter = slideInVertically {
                // Slide in from 40 dp from the top.
                with(density) { 40.dp.roundToPx() }
            } + expandVertically(
                // Expand from the top.
                expandFrom = Alignment.Top
            ) + fadeIn(
                // Fade in with the initial alpha of 0.3f.
                initialAlpha = 0.3f
            ),
            exit = slideOutVertically() + shrinkVertically() + fadeOut()
        ) {
            AppTitle()
        }
    }
}

@Composable
fun AnimationSplashScreen(navController: NavHostController) {

    LaunchedEffect(key1 = true) {
        delay(3000)
        navController.popBackStack()
        navController.navigate(Screen.Login.route)

    }
    SplashScreenContent()

}

navigate안에는 어디로 화면이 이동할지 String 값으로 명시를 해줘야하기 때문에 sealed class를 이용해서 사용한다.

sealed class Screen(val route : String){
    object Splash : Screen("splash_screen")
    object Login : Screen("login_screen")
}

결과

결과