개요
JetPack Compose란?
JetPack Compose는 네이티브 UI를 빌드하기 위한 Android의 최신 권장 도구 키트이다. ▼
JetPack Compose를 사용하는 이유
기존의 빈번한 작업 컨텍스트 전환 해결
XML 기반의 UI를 개발하려면 XML Layout을 정의한 후, 코드 레벨(Java, Kotlin, Swift)에서 View를 연결하여 UI를 관리한다.
XML과 코드 구조를 각각 연동시켜야하기 때문에 빈번한 작업 컨텍스트 전환이 요구된다.
JetPack Compose는 이러한 불편함을 해결해 줄 수 있으며, 직관적이고 단순하게 UI를 구현할 수 있게 해준다.
개념 이해와 빠른 개발
기본적으로 JetPack Compose를 사용하면 XML과 Kotlin 코드를 따로 작성하지 않고 Kotlin으로만 작성하기 때문에 코드 추적이 훨씬 쉬워진다.
레이아웃 시스템 또한 그 개념이 훨씬 단순하기에 코드를 해석하고 추론하기 쉽다.
선언적 API
Flutter와 SwiftUI에서의 그 선언적 UI와 유사한 방식이다.
아래의 Flutter 글에서도 이야기를 했었다. ▼
상태(State)를 넘겨주면 이를 화면(View)으로 표현해주는 방식으로 UI의 속성들을 보다 쉽게 표현하고 구성할 수 있다.
위의 이유들로 인해 보다 빠른 개발을 할 수 있고 JetPack Compose로 넘어가려는 동향이 보인다.
Android의 Compose 전체보기
앞에서 Compose를 사용하는 이유에 대해서 보았으니 이제부터는 간단하게 Compose가 어떤 식으로 앱을 구성하는 지 확인해보자. ▼
@Composable, 구성 가능한 함수
JetPackCompose에서는 UI 구현을 할 때 `@Composable` 이라는 태그가 붙은 구성 가능한 함수를 사용한다.
`@Composable` 함수만 그 내부에서 다른 `@Composable` 함수들을 호출할 수 있다.
즉, `@Composable`이 붙어야만 `@Composable` 함수들을 호출할 수 있다는 것이다.
Text, TextField, Box, Column, Row 등등... 다양한 기본 제공 `@Composable` 함수들을 제공하며, `@Composable` 함수들은 호출이 됐을 때 UI 계층 구조를 형성해준다.
Activity
Compose를 사용하면 `Activity`가 앱의 진입점으로 사용이 된다.
`manifests/AndroidManifest.xml`에 명시된 대로 `MainActivity`가 기본 진입점으로 설정이 되며 아래의 템플릿대로 설정이 된다. ▼
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
여기서 `TestAppTheme`은 프로젝트 생성시 기본 제공되는 `@Composable` 함수이며, `ui/theme/Theme.kt` 에 명시되어있다.
이를 수정하여 앱의 기본 테마를 설정한다.
`Surface` 메소드 안에 `@Composable` 함수를 넣어 첫 진입 화면을 보여줄 수 있다.
Preview
`@Preview`를 붙여, 빌드하지 않고 `@Composable` 함수가 어떻게 구성되는지 확인할 수 있다.
간단하게 @Preview를 붙여서 안드로이드 스튜디오에서 확인할 수 도 있고, ▼
@Preview
@Composable
fun TestPreview() {
...
}
아래와 같이 인자를 넣어서 옵션을 추가한 뒤 확인할 수 도 있다. ▼
@Preview(showBackground = true, name = "Preview")
@Composable
fun TestPreview() {
TestTheme {
Greeting(name = "Android")
}
}
UI 조절 : Modifier
Compose에서는 `Modifier`를 통해 UI를 조절한다.
Surface와 Text, 그리고 그 외로 기본적으로 제공하는 Composable 함수들은 `Modifier`를 통해 UI의 배치 방식을 결정한다.
조금 더 정확하게 표현하면, `Modifier`가 상위 요소의 레이아웃 내에서 현재의 UI 요소가 어떻게 배치가 되고 표현되며 동작하는지를 알려준다. (작성하는 우리는 결정하는 것이지만, 실제로는 위에 알려주는 것이라고 볼 수 있다.)
아래의 코드와 같이 `Modifier`에 `.padding`, `.clickable`과 같은 여러 수정자를 chaining을 통해 추가할 수 있다.
Box(
modifier = Modifier
.padding(top = 10.dp)
.clickable {
...
}
)
Composable 재사용
Composable한 함수는 그 내부에 Composable한 함수를 호출할 수 있다.
UI 요소가 많아지게 되면 Composable 함수들이 중첩이 되고, 그로 인해 코드의 가독성이 상당히 줄어들 수 있다.
(Flutter보다는 덜 그러지만... Compose에도 Flutter의 문제점이 나오는 것을 보니 선언적 UI들의 공통적인 문제점인거 같기도 하다.)
이런 문제를 해결하기 위해 중첩된 요소들을 독립적으로 분할하여 새로운 요소로 만들 수 있다. ▼
이렇게 분리된 요소들은 다른 요소에 재사용할 수 있고, 이렇게 분리하게 되면 들여쓰기 단계가 줄어들어 더욱 더 보기 좋은 코드가 된다.
Compose는 앞에서 본 것들과 같은 요소들로 이루어져 있다.
`Activity`와 `@Composable`로 전체적인 UI가 구성되며, `@Composable`들은 `Modifier`를 통해 상위 레이아웃에게 해당 요소가 어떻게 보여질 지 알려준다.
그리고 이 `@Composable`들은 각각이 독립적으로 구성이 가능하기에 UI요소들을 분리하여 구현 후 재사용할 수 있다.
결론적으로 레고 조각과도 같은 Composable들을 Modifier로 정의한 뒤, 재사용 및 모듈화를 통해 전체적인 UI를 구성한다고 할 수 있다.
마치며
이번에는 간단하게 Compose가 전체적으로 어떤 구성인지를 확인해보았다.
Flutter로 앱 개발을 하다가 Compose로 넘어오게 되었는데, 전체적인 구성이 Flutter와 매우 비슷해서 금방 익힐 수 있었다.
(둘 다 구글이 만든거에 선언형이라 비슷한 거 같기도 하다.)
물론 처음에는 Modifier가 약간은 생소해서 조금 애먹었지만, 조금씩 구현해보니 쉽다고 느껴졌다.
다음에는 전체 레이아웃과 상태에 대해서 학습할 예정이다.
모두 화이팅이다...!
'Develop > AndroidOS' 카테고리의 다른 글
[Android] Compose BOM (0) | 2024.06.25 |
---|---|
[Android] Dependency Injection (DI) (0) | 2024.06.14 |
[Android][Compose] State Hoisting (0) | 2024.06.13 |
[Android][Compose] Compose의 레이아웃 (0) | 2024.06.13 |