기존의 UI는 명령형 방식이었지만, Compose는 선언형 방식. UI가 어떻게 보일지에 대한 구현에서 무엇을 보여주면 되는지에 대한 구현으로 변경.
뷰의 상태만 선언하여 구현 부분은 프레임 워크에게 맡기는 방식.
데이터가 변경되면 프레임 워크가 알아서 해당 함수들을 재호출하여 View를 업데이트. 적은 코드, 유지보수, 재사용 및 확장성 용이.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeExampleTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeExampleTheme {
Greeting("Android")
}
}
**setContent()**는 기존의setContentView()메서드와 동일한 동작을 하는 확장 함수. 다만, (@Composable) -> Unit타입의 컴포즈 UI를 구현해줘야함.
Theme -> Surface -> TextView로 컴포저블이 다른 컴포저블을 호출하는 계층 구조로 이루어져 있음.
@Composable 어노테이션이 붙은 메서드들은 대문자로 시작하고 있습니다.
@Preview 어노테이션을 붙이면 안드로이드 스튜디오의 오른편에서 바로 UI를 확인 가능. @Preview 어노테이션을 붙인 메서드는 인자를 가질 수 없음
***ComponentActivity()***를 상속받고 있음.
AppCompatActivity는 FragmentActivity를 상속받고 Fragment Activity는 ComponentActivity를 상속받음.
ComponentActivity에는 Compose 전용 앱에 필요한 모든 부분이 있음.
Modifier
컴포즈에 내장된 코틀린 클래스.
단일 객체 안에서 컴포저블에 광범위한 프로퍼티를 설정할 수 있음.
한 컴포저블에서 생성하고 설정한 뒤 다른 컴포저블에 전달되고, 적용되기 전에 추가로 수정할 수도 있음.
어떻게 배치하고 그릴지, 행동할지 등을 결정할 수 있음.
Composable의 크기, 레이아웃, 동작 및 모양 변경, 사용자 입력 처리, 클릭 기능 등.
Modifier의 순서는 결과에 영향을 주기 때문에 중요합니다
Compose의 State
Compose는 선언형 방식. 그래서 화면을 변경하기 위해서는 Composable function에 변경된 데이터를 전달하여 다시 호출하는 방법뿐.
Compose는 State를 런타임에 데이터가 변경되면 이를 Observing 하고 있다가 자동으로 재호출하여 UI를 그리는 방법을 제공합니다. 이를 재구성 Recomposing이라고 합니다. 이것이 가능한 이유는 custom kotlin complier plugin을 내부적으로 사용하고 있기 때문.
Composable은 함수가 재시작될 때마다 초기화되기 때문에 상태 값을 지역 변수로 저장하면 재구성이 될 때마다 함수가 새로 호출되기 때문에 저장된 상태 값은 유지되지 않습니다.
상태 값을 계속 유지하려면 remember라는 delegate을 사용함. 만약Configuration변경이 발생한다면, 상태 값의 유지를 보장하지 못하므로 remeberSaveable을 사용해야함.
Composable에서 상태를 저장하고, 상태가 변경되었을 때 재구성을 추적하려면 **mutableStateOf()**를 이용해 MutableState를 생성하여 사용.
mutableListOf()나 ArrayList<T> 처럼 변경되는 객체는Compose의State로 사용하지 않음. 변경이 되더라도Observing할 수 없기 때문.
remember
단순 remeber 사용
구조분해 사용
by 사용 (Delegation)
mutable / immutable 변수 둘다 사용 가능
1. val mutableState = remember { mutableStateOf(default) }
2. var value by remember { mutableStateOf(default) }
3. val (value, setValue) = remember { mutableStateOf(default) }