
위의 책을 간단하게 정리하면서 블로그를 작성할 예정입니다.
기존 개발방식은 XML 파일에 사용자 인터페이스(UI, User Interface)를 정의하고 액티비티(Activity)에 연결하는 개발방식
⇒ 당시 앱이 작고 개발자는 소수의 디바이스만 지원하면 됐기 때문에 문제 X
새로운 플랫폼 버전 & 안드로이드 새로운 기술들 추가됨
구글은 안드로이드 뷰 시스템을 이해하기 쉽게 유지하려고 최선을 다했지만 복잡성 증가함
특히 목록을 스크롤하거나 애니메이션과 같은 기본 작업에도 많은 양의 사용구 코드가 필요함
이러한 문제는 안드로이드에만 국한된 문제 X
대부분의 문제는 흔히 명령적 접근 방식 이라 불리는 UI 툴킷을 사용하는 방식에서 발생함
해결책은 패러다임을 전환
⇒ 웹 프레임워크인 리액트(React)는 처음으로 선언적 접근 방식을 대중화시킴
다른 플랫폼과 프레임워크도 이를 따름
EX) Flutter, SwiftUI
Jetpack Compose 는 구글이 안드로이드로 만든 선언적 UI 프레임워크이며 UI 를 만드는 작업을 극적으로 단순화함
컴포저블 함수 ⇒ 컴포즈 앱의 핵심 구성 요소
@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() 함수는 name과 nameEntered라는 두 개의 매개변수가 필요합니다.
이 두 매개변수가 어떻게 사용되는지는 ‘인사말 출력’ 절에서 확인할 수 있습니다. 지금은 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.value나 nameEntered.value 와 같은 방식으로 값에 접근 할 수 있습니다.
onValueChange 는 텍스트를 변경하는 일이 발생하는 경우(사용자가 값을 입력하거나 삭제하는 경우) 호출됩니다.
name.value 가 value = name.value 에도 사용되고 onValueChange = { name.value = it } 모두에 사용되는 이유는 재구성(Recomposition) 에 있습니다.
재구성(Recomposition) : 특정 타입은 소위 재구성을 유발합니다. 지금은 이를 관련된 컴포저블 함수를 다시 그리는 것으로 생각합니다. MutableState 가 이러한 타입에 해당합니다. MutableState 타입의 값을 변경하면 TextField() 컴포저블 함수는 다시 그려지거나 다시 채색됩니다. 이 두 용어 모두 완전히 올바른 것은 아니라는 것만 알아두고 재구성은 3장에서 다룹니다.