- compose에서 MainActivity는 ComponentActivity의 서브클래스로 선언해야 한다.
- compose 도입 이전의 안드로이드 개발 방식의 결과물로 메인액티비티는 onCreate() 형태의 단일 메서드를 구현한다.
- 여기서 onCreate()는 compose 기반 사용자 인터페이스의 다리를 제공한다.
- Compose를 이용해 개발할 때는 Composable 함수를 이용해 기본 블록을 구성해야 한다.
- Composable 함수는 기본적으로 내장되어 있는 것이 있고 개발자가 직접 구현하는 것도 가능하다(@Composable 어노테이션으로 구현한 함수를 프로젝트에서 사용 가능)
- 컴포저블 함수는 반복적으로 사용되는 구성요소를 매번 개발하는 것이 아니라 재활용 가능하도록 하는 역할이다.
- A라는 컴포저블 함수를 사용자가 정의한 경우 A에 대해서 미리보기 컴포저블 함수를 정의할 수 있다.
- @Preview 어노테이션을 통해서 A 컴포저블 함수에 대한 미리보기 컴포저블을 구현할 수 있다.
컴포저블 함수 개요
- composable == component
- @Composable 어노테이션으로 일반 함수와 구별
- 하나의 컴포저블 함수 내에서 다른 컴포저블 함수를 호출하여 컴포넌트 계층을 생성할 수 있다.
- 컴포저블 함수 내에서 표준 함수를 호출하는 것은 가능하지만 표준 함수에서 컴포저블 함수를 호출할 수는 없다.
stateful composable과 stateless composable
- stateful composable에서 state 값을 저장하기 위해서는 remember 키워드와 mutableStateOf 함수를 호출한다.
@Composable
fun DemoScreen() {
var sliderPosition by remember { mutableStateOf(20f) }
}
- 위의 코드에서 DemoScreen() 컴포저블 함수는 상태값을 저장하므로 stateful composable로 간주된다.
@Composable
fun DemoSlider(sliderPosition: Float, onPositionChange: (Float) -> Unit) {
Slider(
modifier = Modifier.padding(10.dp),
valueRange = 20f..40f,
value = sliderPosition,
onValueChange = onPositionChange
)
}
- 위의 함수는 파라미터로 전달받은 상탯값을 이용하지만 스스로 상탯값을 저장하지는 않는다. 따라서 비상태 컴포저블로 간주된다.
컴포저블 함수 구문
@Composable
fun MyFunction() {}
@Composable
fun CustomText(text: String, fontWeight: FontWeight, color: Color) {
Text(text = text, fontWeight = fontWeight, color = color)
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
CustomText(
text = "Hello Compose",
fontWeight = FontWeight.Bold,
color = Color.Magenta
)
}
- 위의 코드에서 @Preview 어노테이션이 붙은 함수를 호출하여 내가 커스터마이징한 컴포넌트에 대한 미리보기를 볼 수 있다.
@Composable
fun CustomSwitch() {
val checked = remember { mutableStateOf(true) }
Column {
Switch(
checked = checked.value,
onCheckedChange = { checked.value = it }
)
if (checked.value) {
Text("Switch is On")
} else {
Text("Switch is Off")
}
}
}
- 이 컴포저블 함수는 switch 버튼을 텍스트와 함께 사용하도록 커스터마이징한 것이다.
- checked 변수는 mutableStateOf의 인스턴스이고 true로 초기화되었기 때문에 checked 변수가 갖는 value의 값은 true 또는 false가 된다.
- Switch의 value 속성에 checked 변수의 value 값으로 초기화하고 onCheckedChange 콜백 함수를 통해서 Switch의 checked가 변경될 때마다 checked.value의 값을 Switch의 checked 값으로 변경한다.
- it 키워드는 onCheckedChange 콜백 함수에서 전달받은 매개변수를 나타낸다. 단일 매개변수에 대해서는 it 키워드로 대체하는 것이 가능하다.
파운데이션 컴포저블과 머티리얼 컴포저블
컴포즈에서 번들로 제공하는 컴포저블은 레이아웃, 파운데이션, 머티리얼 디자인 컴포넌트의 세 가지로 분류할 수 있다.
레이아웃 컴포넌트
- Box
- ConstraintLayout
- BoxWithConstraints
- Row
- Column
파운데이션 컴포넌트
- BaseTextField
- LazyRow
- Canvas
- Shape
- Image
- Text
- LazyColumn
머티리얼 디자인 컴포넌트
- AlertDialog
- RadioButton
- Button
- Scaffold
- Card
- Slider
- CircularProgressIndicator
- Snackbar
- DropdownMenu
- Switch
- CheckBox
- TextField
- FloatingActionButton
- TopAppBar
- LinearProgressIndicator
- BottomNavigation
- ModalDrawer
remember에 대한 이해
var checked = true
val checked = remember { mutableStateOf(true) }
둘의 차이는 뭘까??
- 컴포저블 함수 내에서 checked 변수를 사용해야 하는 상황을 가정
- 두 경우 모두 true -> false, false -> true로 변경하는 것이 가능
- 그러나 var로 remember 없이 선언한 경우에는 다른 화면을 실행하고 다시 돌아왔을 때 매번 초기값으로 설정된다.
- remember를 사용하는 이유는 유저의 동작에 따라 값이 변경되었을 때 이를 기억하기 위해서 사용하는 것.
- 따라서 remember를 사용한 경우에는 유저가 변경한 값을 컴포즈가 기억하고 화면을 다시 그렸을 때 변경된 값이 유지된다.
- 그러므로 변경된 값을 기억해서 유지하고 싶은 상황에는 remember를 사용하자.