JetPack Compose
해당 포스트는 2021년 6월 노션에서 작성된 것을 옮겨온 것임을 미리 알려드립니다.
Jetpack Compose?
안드로이드 용 최신 UI Tool kit. 직관적, 강력, 빠르게 개발 가능함.
코드가 적기 때문에 빠르고 쉬움
기능을 구축하는데 집중하고 UI를 만드는 시간이 줄어들음
7월 오픈 예정
Sample
Jetpack Compose를 사용하기 위해서는 Android Studio Arctic Fox를 다운로드 해야한다.
New - Project - Empty Compose Project 선택
처음 프로젝트를 만들면 다음과 같은 기본 소스가 생성된다.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeBasicsTheme {
// 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() {
ComposeBasicsTheme {
Greeting("Android")
}
}
상단 메뉴에 있는 Split View를 활성화 하면 다음과 같은 미리보기 화면이 제공된다.
Empty Compose Activity 미리보기 화면
미리보기의 경우 함수명에서 보면 알겠듯이 하단의 DefaultPreview()에 의해 보여지게 되며, 재사용을 위해 다음과 같이 함수를 만들어 setContent의 내용이 변경되면 Preview도 함께 변경할 수 있게끔 함수를 작성해준다.
....
setContent {
MyApp()
}
....
@Composable
fun MyApp(){
ComposeBasicsTheme {
Surface(color = MaterialTheme.colors.background) {
Column {
Greeting("Android")
}
}
}
}
....
fun DefaultPreview() {
MyApp()
}
이후 UI 변경 사항은 MyApp()을 통해서 관리하게 되면, 실제 View와 Preview를 같이 업데이트 할 수 있다.
Compose의 함수는 @composable 어노테이션에 의해 지정된다.
이 어노테이션은 이 함수가 데이터를 UI로 변환하기 위한 함수라는 것을 Compose 컴파일러에 알린다.
함수내에 작성된 코드에 의해 UI가 변경되며 이는 Preview에 의해 반영된다.
Surface 함수를 이용하여 배경색상을 바꿔보자.
@Composable
fun Greeting(name: String) {
Surface(color = Color.Yellow) {
Text(text = "Hello $name!")
}
}
또한 함수로 감싸는 것 외에도 정의된 Modifier 인자로 하여 UI의 속성을 정의할 수 있다.
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!",
modifier = Modifier
.background(color = Color.Yellow)
.padding(15.dp)
)
}
또한 함수내에 이벤트를 등록 및 정의할 수 있다.
@Composable
fun CountButton(){
var count : Int = 0
Button(onClick = { count++ }) {
Text(text = "버튼을 ${count}번 눌렀어요")
}
}
다음은 TextButton과 버튼 내부에 onClick 이벤트를 정의한 코드다.
일반적인 코드에서 onClick 이벤트는 다음과 같이 정의되며, 이를 실행하면 버튼에 표기된 숫자가 +1씩 변경될 것이다. 코드를 실행해보자.
????
이벤트가 정상적으로 동작하지 않는 다는 사실을 알 수 있다 (왜시켰어)
count 변수를 다음과 같이 변경하여 실행하여 보자
// var count : Int = 0
var count by remember {
mutableStateOf(0)
}
다음과 같이 동작하는 것을 알 수 있다.
위와 같이 일반적인 자료형을 변수로 사용했을 때 아무런 일도 일어나지 않는 이유는 Compose에서의 컴포지션 및 리컴포지션 작동 방식 때문이다.
컴포지션은 UI를 기술하는 역할을 하며 컴포저블을 실행하면 생성됩니다. 컴포지션은 UI를 기술하는 컴포저블의 트리 구조입니다.
컴포지션은 초기 컴포지션을 통해서만 생성되고 리컴포지션을 통해서만 업데이트될 수 있습니다. 컴포지션을 수정하는 유일한 방법은 리컴포지션을 통하는 것입니다
컴포저블을 업데이트 하려면 상태를 나타내는 값을 전달하고, 값이 변경될 때에는 상태를 업데이트 해주어야 한다. 이를 위해 상태를 추가하려면 remember { mutableStateOf() }를 사용하며 해당 상태가 변경되면 UI 역시 같이 업데이트 된다.
마지막으로 컴포넌트에 Animation을 등록해보자.
해당 코드는 컴포넌트에 간단한 애니메이션만 등록할 예정이며, 자세한 내용은 Compose Animation 섹션을 참고하도록 하자.
위에서 만들어둔 CountButton을 짝수만큼 눌렀을 때 푸른 색으로, 홀수만큼 눌렀을 때는 회색으로 색상이 변하는 애니메이션을 추가하고자 한다.
우선 함수내에 버튼의 색상을 정의한다
val targetColor by animateColorAsState(
targetValue = if(countState % 2 == 0) Color.Blue else Color.DarkGray
)
Button(onClick = { countState++ },
colors = ButtonDefaults.buttonColors(backgroundColor = targetColor)) {
Text(text = "버튼을 ....
해당 코드를 실행 시 버튼의 색상이 교차로 변경되는 것을 확인할 수 있다.
그렇다면 색상이 자연스럽게 변경되게 하려면 어떻게 해야할까?(사실 지금도 딱히 어색하진 않다)
상태를 선언하는 함수에서 유추할 수 있듯 해당 상태내에 animationSpec을 정의해주면 된다.
해당 상태를 정의하는 코드를 다음과 같이 수정한 뒤 코드를 실행해보자.
val targetColor by animateColorAsState(
targetValue = if(countState % 2 == 0) Color.Blue else Color.DarkGray,
animationSpec = tween(durationMillis = 1000)
)
짠! 자연스럽게 버튼의 색상이 변경되는 것을 확인할 수 있다.
다음 포스트는 컴포즈 중급자를 위한 포스트가 될 것이며 틈틈히 공부해서 최대한 빠르게 다음 포스트를 업데이트 하도록 노력하겠다.
참고자료
'Development > Android' 카테고리의 다른 글
[번역] CameraX 기초 예제 - Part 3 (0) | 2022.02.11 |
---|---|
[번역] CameraX 기초 예제 - Part2 (0) | 2022.02.11 |
[번역] CameraX 기초 예제 - Part1 (0) | 2022.02.11 |
[잡담] 안드로이드 디버깅 시, 에어팟 음질 저하 현상 (0) | 2022.02.09 |
The min CompileSdk specified in a dependency's AAR metadata is greater than this module's compileSdkVersion (0) | 2022.02.09 |