[Android] Jetpack Compose 로 개발하는 안드로이드 UI - 1장

안세홍·2024년 9월 3일
post-thumbnail

위의 책을 간단하게 정리하면서 블로그를 작성할 예정입니다.

Jetpack Compose

기존 개발방식의 문제점

기존 개발방식은 XML 파일에 사용자 인터페이스(UI, User Interface)를 정의하고 액티비티(Activity)에 연결하는 개발방식

⇒ 당시 앱이 작고 개발자는 소수의 디바이스만 지원하면 됐기 때문에 문제 X

새로운 플랫폼 버전 & 안드로이드 새로운 기술들 추가됨

구글은 안드로이드 뷰 시스템을 이해하기 쉽게 유지하려고 최선을 다했지만 복잡성 증가함

특히 목록을 스크롤하거나 애니메이션과 같은 기본 작업에도 많은 양의 사용구 코드가 필요함

이러한 문제는 안드로이드에만 국한된 문제 X

대부분의 문제는 흔히 명령적 접근 방식 이라 불리는 UI 툴킷을 사용하는 방식에서 발생함

해결책

해결책은 패러다임을 전환

⇒ 웹 프레임워크인 리액트(React)는 처음으로 선언적 접근 방식을 대중화시킴

다른 플랫폼과 프레임워크도 이를 따름

EX) Flutter, SwiftUI

Jetpack Compose 는 구글이 안드로이드로 만든 선언적 UI 프레임워크이며 UI 를 만드는 작업을 극적으로 단순화함

1장

  • 컴포저블 함수와 인사
  • 미리 보기 사용
  • 컴포즈 앱 실행

컴포저블 함수와 인사

컴포저블 함수 ⇒ 컴포즈 앱의 핵심 구성 요소

환영 인사 나타내기

@Composable
fun Welcome() {
    Text(
        text = stringResource(id = R.string.welcome),
        style = MaterialTheme.typography.subtitle1
    )
}

컴포저블 함수는 @Composable 어노테이션으로 손쉽게 식별 가능

어노테이션 : 다른 프로그램에게 유용한 정보를 제공하기 위해 사용되는 것으로 주석과 같은 의미를 가진다.

Text()를 지금 이대로 호출하려면 다음과 같이 임포트문을 추가

import androidx.compose.material.Text

Text() 나 다른 머티리얼 디자인 요소를 사용하려면 build.gradle 파일에 androidx.compose.material:material 구현 의존성(implementation dependancy)를 반드시 포함해야 합니다.

implementation "androidx.compose.material:material:$compose_version"

다음 컴포저블

@Composable
fun Greeting(name: String) {
    Text(
        text = stringResource(id = R.string.hello, name),
        textAlign = TextAlign.Center,
        style = MaterialTheme.typography.subtitle1
    )
}

여기서는 이전 컴포저블과 다르게 stringResource() 에 매개변수를 추가로 받았습니다. 이는 플레이스홀더(placeholder) 를 실제 문구로 교체할 때 매우 편리합니다. 아래는 R.string.hello 에 정의된 문자열입니다.

<string name="hello">Hello, %1$s.\nNice to meet you.</string>

textAlign 는 텍스트를 가로 기준 어떻게 배치할지를 명시합니다. Center ⇒ 중앙

열, 텍스트 필드, 버튼 사용

텍스트 입력 필드와 완료 버튼은 동일선상에 위치하게 됩니다.

매우 일반적인 패턴이기 때문에 Row() 라는 컴포저블 함수를 제공합니다.

androidx.compose.foundation.layout 패키지에 포함되어 있습니다.

@Composable
fun TextAndButton(name: MutableState<String>, 
									nameEntered: MutableState<Boolean>) {
    Row(modifier = Modifier.padding(top = 8.dp)) {
        ...
    }
}

TextAndButton() 함수는 namenameEntered라는 두 개의 매개변수가 필요합니다.

이 두 매개변수가 어떻게 사용되는지는 ‘인사말 출력’ 절에서 확인할 수 있습니다. 지금은 MutableState 타입은 무시합니다.

Row()에 함수 modifier라는 매개변수를 받습니다. 변경자(Modifier)는 젯팩 컴포즈의 핵심 기술로 컴포저블 함수의 외형과 행위에 영향을 줍니다. 자세한건 3장에서 다룹니다.

padding(top = 8.dp) ⇒ 8픽셀만큼 패딩 추가입니다.

사용자가 이름을 입력하는 텍스트 입력 필드 코드

TextField(
    value = name.value,
    onValueChange = {
        name.value = it
    },
    placeholder = {
        Text(text = stringResource(id = R.string.hint))
    },
    modifier = Modifier
        .alignByBaseline()
        .weight(1.0F),
    singleLine = true,
    keyboardOptions = KeyboardOptions(
        autoCorrect = false,
        capitalization = KeyboardCapitalization.Words,
    ),
    keyboardActions = KeyboardActions(onAny = {
        nameEntered.value = true
    })
)

마찬가지로 TextField() 는 android.compose.material 패키지에 포함되어 있습니다. 여기에서 TextAndButton()에 전달된 name과 nameEntered 변수를 사용했다는 점을 참고해야 됩니다.

이들의 타입은 MutableState 이며, MutableState 객체는 변경할 수 있는 값이라는 특징을 갖습니다.

name.valuenameEntered.value 와 같은 방식으로 값에 접근 할 수 있습니다.

onValueChange 는 텍스트를 변경하는 일이 발생하는 경우(사용자가 값을 입력하거나 삭제하는 경우) 호출됩니다.

name.valuevalue = name.value 에도 사용되고 onValueChange = { name.value = it } 모두에 사용되는 이유는 재구성(Recomposition) 에 있습니다.

재구성(Recomposition) : 특정 타입은 소위 재구성을 유발합니다. 지금은 이를 관련된 컴포저블 함수를 다시 그리는 것으로 생각합니다. MutableState 가 이러한 타입에 해당합니다. MutableState 타입의 값을 변경하면 TextField() 컴포저블 함수는 다시 그려지거나 다시 채색됩니다. 이 두 용어 모두 완전히 올바른 것은 아니라는 것만 알아두고 재구성은 3장에서 다룹니다.

profile
나만의 개발 일기

0개의 댓글