Jetpack Compose Essentials 트레이닝 코스의 4번째 챕터인 코드랩 Write your first Compose app을 정리한 글입니다.
Jetpack Compose는 UI 개발을 단순화하기 위해 설계되었다. 컴포즈는 코틀린만을 이용함으로써 반응형 프로그래밍을 더 쉽고 간결하게 구현할 수 있다.
컴포즈는 완전한 선언형이다. UI의 형태와 동작이 모두 정의되어 있는 함수를 호출함으로써 UI를 그린다. (View System은 형태와 동작의 정의가 분리되어 있음)
함수 내부의 상태 값이 변경되면 프레임워크가 자동으로 함수를 재호출하여 UI 계층을 업데이트한다.
Composable function(컴포저블 함수)는 일반 함수에 @Composable 어노테이션을 붙인 것을 말한다. composable이라고 줄여 말하기도 한다. (여기선 편하게 컴포즈 함수라고 하겠음)
컴포즈 함수는 다른 컴포즈 함수 안에서만 호출될 수 있다.
UI 요소를 그리는데 필요한 것은 함수뿐이다. UI 요소를 정의하고 싶으면 컴포즈 함수를 정의하고, UI를 그리거나 업데이트 하고 싶으면 함수를 호출한다.
컴포즈를 사용하면 XML을 사용하는 것에 비해 UI 요소를 작고 재사용한 단위로 더욱 쉽게 쪼갤 수 있다.
File > New > New Project에서 Empty Compose Activity (Material3)를 선택해서 새 프로젝트를 생성하자. (API 21 이상을 선택해야 컴포즈 사용 가능)
그러면 자동으로 컴포즈를 사용할 수 있도록 프로젝트가 세팅된다.
컴포즈 프로젝트를 생성하면 아래와 같은 코드를 볼 수 있다.
@Composable
private fun Greeting(name: String) {
Text(text = "Hello $name!")
}
Greeting: 사용자 정의 컴포즈 함수
Text: 라이브러리에서 제공하는 컴포즈 함수
컴포즈에서도 액티비티는 앱의 진입점 역할을 한다.
View System처럼 setContent 함수를 호출하여 UI를 그리는데 다른 점은 람다 안에 컴포즈 함수를 호출한다.
Greeting이 그리는 UI를 보고 싶으면 preview 기능을 이용할 수 있다.
프리뷰는 파라미터가 없거나 디폴트 값이 있는 파라미터를 갖는 컴포즈 함수에 @Preview 어노테이션을 붙여 정의한다.
@Preview(showBackground = true, name = "Text preview")
@Composable
fun DefaultPreview() {
BasicsCodelabTheme {
Greeting(name = "Android")
}
}
(BasicsCodelabTheme은 테마 설정과 관련된 함수로 프로젝트에 붙인 이름에 따라 다르며 ui/theme/Theme.kt 파일에 정의되어 있는 것을 사용해야 한다.)
DefaultPreview 함수의 프리뷰 결과이다.
오른쪽 상단에서 split 모드나 Design 모드를 클릭하여 확인할 수 있다.
Surface 함수로 Text 함수를 감싸면 텍스트에 배경색을 지정할 수 있다. Surface는 컬러를 인자로 받는다. 색상은 MaterialTheme.colorScheme.primary를 사용해보자.
@Composable
private fun Greeting(name: String) {
Surface(color = MaterialTheme.colorScheme.primary) {
Text (text = "Hello $name!")
}
}
MaterialTheme는 구글이 만든 Material Design 시스템 개념이 적용되어 있다. UI 속성들을 편하게 가져다 쓸 수 있다.
아래 결과처럼 Surface 안에 있는 컴포넌트들은 Surface의 배경 색상 위에 그려진다.
그런데 신기하게도 텍스트 색상이 자동으로 흰색으로 바뀌었다. 이것은 Surface 덕분이다.
Surface는 androidx.compose.material3.Surface에서 보듯 머티리얼 컴포넌트이다. 그래서 여러 편리한 기능을 제공하는데 Text 색상 변경도 그 중 하나이다. 여기서는 Surface가 primary 컬러로 지정돼서 Text 색상이 onPrimary로 변경됐다.
(절대적인 색상에 따라 바뀌는 것은 아니고 primary, secondary와 같이 머티리얼 color scheme으로 설정했을 때 머티리얼 색상 시스템을 기반으로 변경되는 듯하다.)
대부분 컴포즈 함수는 modifier라는 옵션 파라미터를 갖고 있다. Modifier는 그 UI 요소가 부모 레이아웃 안에서 어떻게 배치되고 움직이는지를 설정한다.
예를 들어 padding을 설정하고 싶으면 Modifier.padding()을 사용한다.
@Composable
private fun Greeting(name: String) {
Surface(color = MaterialTheme.colorScheme.primary) {
Text(text = "Hello $name!", modifier = Modifier.padding(24.dp))
}
}