https://developer.android.com/jetpack/compose/tutorial?hl=ko
Android Compose 튜토리얼 | Android 개발자 | Android Developers
Jetpack Compose는 네이티브 Android UI를 빌드하기 위한 최신 도구 키트입니다. Jetpack Compose는 더 적은 수의 코드, 강력한 도구, 직관적인 Kotlin API로 Android에서의 UI 개발을 간소화하고 가속화합니다. 이
developer.android.com
앱개발자로 스타트업에 취업하게 되었는데 내부 사정으로 당장 받을 일이 없는 상황...
긍정적으로 생각해서 평소에 관심있던 Jetpack Compose를 공부 해보자는 계획을 했습니다.
간단하게 둘러본적은 있지만 아예 모르기때문에 공식 튜토리얼부터 차근차근 시작해보자.
0. Project 생성

먼저 NewProject -> Phone and Tablet 탭 -> Empty Compose Activity를 선택해주자.
1. 텍스트
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material.Text
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text("Hello world!")
}
}
}
가장 기본이 되는 Text입니다. Compose는 기본적으로 콘텐츠 블록을 정의하고 구성 가능한 함수를 호출하면 됩니다.
// ...
import androidx.compose.ui.tooling.preview.Preview
@Composable
fun MessageCard(name: String) {
Text(text = "Hello $name!")
}
@Preview
@Composable
fun PreviewMessageCard() {
MessageCard("Android")
}
위와 같은 화면이지만 함수로 빼낸코드입니다. 함수를 구성 가능하게 하려면 @Composable 주석을 추가해야 합니다. 이렇게 하려면 이름을 전달받는 MessageCard 함수를 정의하고 이를 사용하여 텍스트 요소를 구성합니다.
다음으로 Compose를 미리보기 하기 위해서는 아래와같이 @Preview 주석을 추가해야합니다. 단순히 미리보기 뿐만아니라 클릭 이벤트와 같은 동작또한 미리보기로 가능하게 됩니다.
2. 레이아웃
// ...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MessageCard(Message("Android", "Jetpack Compose"))
}
}
}
data class Message(val author: String, val body: String)
@Composable
fun MessageCard(msg: Message) {
Text(text = msg.author)
Text(text = msg.body)
}
@Preview
@Composable
fun PreviewMessageCard() {
MessageCard(
msg = Message("Colleague", "Hey, take a look at Jetpack Compose, it's great!")
)
}
위 코드와같이 Text를 2개 이상 쓰려고하면 겹쳐서 보이게됩니다. 당연히 우리의 의도는 이것이 아닐테니 우리는 Row 또는 Column을 사용 해야 합니다.
// ...
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.ui.res.painterResource
@Composable
fun MessageCard(msg: Message) {
Row {
Image(
painter = painterResource(R.drawable.profile_picture),
contentDescription = "Contact profile picture",
)
Column {
Text(text = msg.author)
Text(text = msg.body)
}
}
}

위와같이 Column태그로 감싸주게되면 세로로, Row태그로 감싸주게되면 가로로 정렬되어 보여지게됩니다.
3. 디자인 및 속성
- 이미지 속성
Image(
painter = painterResource(R.drawable.profile_picture),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)
)
- 텍스트 속성
Text(
text = msg.author,
color = MaterialTheme.colors.secondaryVariant,
style = MaterialTheme.typography.subtitle2
)
- 공백(Margin)
Spacer(modifier = Modifier.height(4.dp))
4. 목록 및 애니메이션
개인적으로 이 부분에서 Compose의 매력을 많이느꼇다.
@Composable
fun Conversation(messages: List<Message>) {
LazyColumn {
items(messages) { message ->
MessageCard(message)
}
}
}
@Preview
@Composable
fun PreviewConversation() {
ComposeTutorialTheme {
Conversation(SampleData.conversationSample)
}
}
여러개의 리스트를 보여주는 코드인데, 이걸 원래 xml로 만들려고하면 RecyclerView, Adapter, Viewholder.. 등등 엄청나게 많은 리소스가 필요한데 이정도 코드로 구현이 가능하다는점에서 놀라웠다.
@Composable
fun MessageCard(msg: Message) {
Row(modifier = Modifier.padding(all = 8.dp)) {
Image(
painter = painterResource(R.drawable.profile_picture),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colors.secondaryVariant, CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
// We keep track if the message is expanded or not in this
// variable
var isExpanded by remember { mutableStateOf(false) }
// We toggle the isExpanded variable when we click on this Column
Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
Text(
text = msg.author,
color = MaterialTheme.colors.secondaryVariant,
style = MaterialTheme.typography.subtitle2
)
Spacer(modifier = Modifier.height(4.dp))
Surface(
shape = MaterialTheme.shapes.medium,
elevation = 1.dp,
) {
Text(
text = msg.body,
modifier = Modifier.padding(all = 4.dp),
// If the message is expanded, we display all its content
// otherwise we only display the first line
maxLines = if (isExpanded) Int.MAX_VALUE else 1,
style = MaterialTheme.typography.body2
)
}
}
}
채팅을 누르면 확장되는 코드이다. 코드가 적혀있는 형식이 낯설어서그렇지 잘보면 간단한 코드이다.
다만 주목해야할부분은 다음코드이다.
var isExpanded by remember { mutableStateOf(false) }
컴포즈 UI는 새롭게호출되기때문에 remember를 사용해서 변경된 상태를 기억해주어야 한다.
일단은 간단하게 튜토리얼을 진행해보았는데 확실히 Compose에 시간을 들여서 공부 해볼만한것 같다고 느꼇다. 코드가 매우 짧고 간단해지고 매번 안드로이드 프로젝트를 진행할때마다 xml 파일이 늘어나는게 불만이였는데 이런 문제점을 해결해주는것같다.
물론 아직까지는 간단한 코드만봣고 큰프로젝트에 적용가능할지는 미지수네요.
그래도 계속해서 공부는 해볼예정
'Programming > Kotlin' 카테고리의 다른 글
| 코틀린 Retrofit2 Response 반환값 null 인경우 (1) | 2023.02.09 |
|---|---|
| CollapsingToolbarLayout 와 Viewpager2 호환문제 (0) | 2023.02.03 |
| [코틀린] constraint 속성 동적으로 추가 (0) | 2022.08.22 |
| 코틀린(Kotlin)의 조건문(if) 활용법 (0) | 2022.08.11 |
| [Kotlin]Cannot invoke setValue on a background thread 오류 (0) | 2021.06.15 |