코틀린 안드로이드 앱개발 강좌, 메신저 앱의 인트로 화면 만들기

안녕하세요! 이번 강좌에서는 코틀린을 활용하여 안드로이드 메신저 앱의 인트로 화면을 만드는 방법을 자세히 설명하겠습니다. 인트로 화면은 사용자가 앱을 처음 실행했을 때 보이는 화면으로, 보통 로고나 슬로건 등을 포함하고 있습니다. 사용자가 앱에 대한 기대감을 갖게 만드는 중요한 요소입니다.

1. 프로젝트 생성

안드로이드 스튜디오를 실행한 후, 새로운 프로젝트를 생성합니다. 제안된 템플릿 중에서 ‘Empty Activity’를 선택하고, 프로젝트명을 ‘MessengerApp’으로 설정합니다. 이후 코틀린을 언어로 선택합니다.

2. Gradle 설정

Jetpack Compose를 사용할 예정이므로, Gradle 파일에 필요한 의존성을 추가해야 합니다. build.gradle (Module: app) 파일에 다음과 같이 작성합니다:

dependencies {
    implementation "androidx.compose.ui:ui:1.1.0"
    implementation "androidx.compose.material:material:1.1.0"
    implementation "androidx.compose.ui:ui-tooling-preview:1.1.0"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0"
    implementation "androidx.activity:activity-compose:1.5.0"
}

이 설정은 Jetpack Compose와 관련된 라이브러리를 가져옵니다. 이제 Gradle을 Sync하여 설정을 완료합니다.

3. 인트로 화면 UI 구성

메신저 앱의 인트로 화면에는 로고와 슬로건이 들어갑니다. 인트로 화면을 구성하기 위해서는 새로운 Composable 함수를 만들어야 합니다. MainActivity.kt 파일을 열고, 다음 코드를 추가합니다:

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.tooling.preview.Preview

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

@Composable
fun IntroScreen() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.logo),
            contentDescription = null,
            Modifier.size(128.dp)
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            text = "당신의 메시지를 연결합니다!",
            fontSize = 24.sp,
            fontWeight = FontWeight.Bold
        )
    }
}

@Preview
@Composable
fun PreviewIntroScreen() {
    IntroScreen()
}

여기서는 IntroScreen이라는 Composable 함수를 만들어 인트로 화면을 구성하였습니다. Column을 사용하여 로고 이미지와 슬로건 텍스트를 수직으로 배치했습니다. 로고는 drawable 폴더에 logo.png 파일을 추가하여 사용하고, 슬로건은 원하는 메시지로 변경할 수 있습니다.

4. 애니메이션 효과 추가

인트로 화면에서 단순히 로고와 텍스트만 표시하는 것이 아니라, 애니메이션 효과를 추가하여 사용자에게 시각적으로 더 매력적으로 만들어줄 수 있습니다. androidx.compose.animation 라이브러리를 사용하여 애니메이션을 추가해보겠습니다.

아래의 코드를 IntroScreen 함수 내부에 추가하여 Fade-in 애니메이션을 구현할 수 있습니다:

import androidx.compose.animation.core.*
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun IntroScreen() {
    val transition = rememberInfiniteTransition()
    val alpha by transition.animateFloat(
        initialValue = 0f,
        targetValue = 1f,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 2000, easing = FastOutSlowInEasing)
        )
    )

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
            .graphicsLayer(alpha = alpha),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.logo),
            contentDescription = null,
            Modifier.size(128.dp)
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            text = "당신의 메시지를 연결합니다!",
            fontSize = 24.sp,
            fontWeight = FontWeight.Bold
        )
    }
}

위 코드에서 rememberInfiniteTransition()을 사용하여 애니메이션을 정의했습니다. animateFloat 함수를 통해 알파 값을 조정하여 Fade 효과를 적용합니다.

5. 인트로 시간 설정 및 다음 화면으로 전환

인트로 화면에서 사용자가 특정 시간 후에 다음 화면으로 이동하게 설정할 수 있습니다. 이를 위해 LaunchedEffect를 사용하여 딜레이를 추가합니다. 다음 코드를 IntroScreen 함수에 추가합니다:

import androidx.compose.runtime.rememberCoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@Composable
fun IntroScreen() {
    val coroutineScope = rememberCoroutineScope()
    
    LaunchedEffect(Unit) {
        delay(3000) // 3초 대기
        // 다음 화면으로 전환하는 로직 추가
    }
    // 나머지 코드 ...
}

여기서 3초 동안 대기한 후 다음 화면으로 전환하는 로직을 추가해야 합니다. 예를 들어, MainScreen이라는 함수로 전환할 수 있습니다. MainScreen 함수를 작성하고, 인트로 화면이 끝난 후 해당 함수를 호출하도록 변경합니다.

6. 전체 코드 정리

지금까지의 내용을 종합하여 MainActivity.kt 파일을 완성해보겠습니다.

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.animation.core.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

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

@Composable
fun IntroScreen() {
    val coroutineScope = rememberCoroutineScope()
    val transition = rememberInfiniteTransition()
    val alpha by transition.animateFloat(
        initialValue = 0f,
        targetValue = 1f,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 2000, easing = FastOutSlowInEasing)
        )
    )

    LaunchedEffect(Unit) {
        delay(3000)
        // 다음 화면으로 전환하는 로직 추가
    }
    
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp)
            .graphicsLayer(alpha = alpha),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Image(
            painter = painterResource(id = R.drawable.logo),
            contentDescription = null,
            Modifier.size(128.dp)
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            text = "당신의 메시지를 연결합니다!",
            fontSize = 24.sp,
            fontWeight = FontWeight.Bold
        )
    }
}

@Composable
fun MainScreen() {
    // 다음 화면 UI 구성
}

@Preview
@Composable
fun PreviewIntroScreen() {
    IntroScreen()
}

7. 다음 화면 구성

인트로 화면이 끝난 후 사용할 MainScreen 함수를 구성합니다. 기본적으로 메신저 앱의 메인 화면 UI를 설계해야 합니다. 다음은 간단한 메인 화면 구성의 예입니다:

@Composable
fun MainScreen() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "메신저 앱에 오신 것을 환영합니다!",
            fontSize = 32.sp,
            fontWeight = FontWeight.Bold
        )
        // 추가적인 UI 구성
    }
}

이제 IntroScreen에서 MainScreen으로 전환하는 로직을 추가해야 합니다. setContent 함수 내에서 인트로 화면 후 메인 화면으로 전환하도록 수정합니다.

super.onCreate(savedInstanceState)
setContent {
    var isIntroVisible by remember { mutableStateOf(true) }
    if (isIntroVisible) {
        IntroScreen { isIntroVisible = false }
    } else {
        MainScreen()
    }
}

그리고 IntroScreen 함수의 매개변수로 람다 함수를 추가하여 메인 화면으로 전환할 수 있도록 합니다:

@Composable
fun IntroScreen(onFinish: () -> Unit) {
    // ...
    LaunchedEffect(Unit) {
        delay(3000)
        onFinish()
    }
}

8. 폴더 구조 및 이미지 추가

프로젝트의 res/drawable 폴더에 인트로 화면에서 사용할 로고 이미지를 추가해야 합니다. 이미지는 logo.png라는 이름으로 추가합니다. 이렇게 하면 painterResource(id = R.drawable.logo)로 로고를 가져올 수 있습니다.

9. 최종 테스트

모든 설정과 구성 후, 앱을 실행하여 인트로 화면과 메인 화면이 원활하게 전환되는지 테스트합니다. 인트로 화면에서 로고와 슬로건이 3초 동안 나타난 후 메인 화면으로 부드럽게 전환되어야 합니다.

10. 결론

이번 강좌에서는 코틀린과 Jetpack Compose를 사용하여 메신저 앱의 인트로 화면을 만드는 방법을 배워보았습니다. 인트로 화면의 디자인과 애니메이션 효과, 그리고 다음 화면으로의 전환 로직까지 구현함으로써, UI 요소들을 효과적으로 구성하는 방법에 대한 기초를 익힐 수 있었습니다.

앞으로 더 많은 안드로이드 앱 개발 주제를 다루며 깊이 있고 다양한 기능을 구현해보세요. 여러분의 개발 여정에 좋은 경험이 되길 바랍니다!