기본 구성
Compose는 선언형 UI로, 기존의 xml을 사용하던 방식과는 다르다.
Activity에 @Composable 어노테이션을 붙여 사용하고, 여러 Compose의 코드들로 UI를 구성할 수 있다.
Compose를 사용했을 때의 장점은
코드 감소, 직관적, 빠른 개발 속도, 강력한 성능이라 할 수 있는데, 왜 이런 장점을 가지는지 공부하며 알아보자!
@Composable
fun MessageCard(msg: Message) {
// Add padding around our message
Row(modifier = Modifier.padding(all = 8.dp)) {
Image(
painter = painterResource(R.drawable.profile_picture),
contentDescription = "Contact profile picture",
modifier = Modifier
// Set image size to 40 dp
.size(40.dp)
// Clip image to be shaped as a circle
.clip(CircleShape)
)
// Add a horizontal space between the image and the column
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(text = msg.author)
// Add a vertical space between the author and message texts
Spacer(modifier = Modifier.height(4.dp))
Text(text = msg.body)
}
}
}
(https://developer.android.com/jetpack/compose/tutorial)
위와 같이 Column, Row를 이용해 Text의 배열을 정의할 수 있다.
modifier를 통해 xml의 속성을 정의하듯, text나 image의 size, color 등등을 모두 정의할 수 있다.
@Composable
fun Conversation(messages: List<Message>) {
LazyColumn {
items(messages) { message ->
MessageCard(message)
}
}
}
@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) }
// surfaceColor will be updated gradually from one color to the other
val surfaceColor: Color by animateColorAsState(
if (isExpanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
)
// 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,
// surfaceColor color will be changing gradually from primary to surface
color = surfaceColor,
// animateContentSize will change the Surface size gradually
modifier = Modifier.animateContentSize().padding(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
)
}
}
}
}
Image의 경우painter를 이용해 drawable을 가져올 수 있고, Spacer를 이용해 margin과 같은 효과를 낼 수 있다.
Material Theme을 그대로 가져와 사용할 수 있고
val surfaceColor: Color by animateColorAsState(
if (isExpanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
)
이렇게 animateColorAsState를 대리자로 설정하여, surfaceColor라는 변수의 값을 설정할 수 있다.
여기서 remember에 대해 이해하기 위해 Compose의 State에 대해 추가로 공부하여 포스팅해보자!
@Composable
fun Conversation(messages: List<Message>) {
LazyColumn {
items(messages) { message ->
MessageCard(message)
}
}
}
또 LazyColumn의 items를 이용하면, RecyclerView를 손쉽게 구현할 수 있다. 기존 RecyclerView는 구현하기 까다로운 부분이 많았는데 (Adater 등등), 이렇게 간단히 설정할 수 있다.
Column, Row, Box, LazyColumn 등의 요소와 modifier를 어떻게 사용하는지 Compose를 기초 구성하는 방법을 기록하기 위해 적어두었다.
'프로그래밍 > Android' 카테고리의 다른 글
Delegate란? (0) | 2021.12.22 |
---|---|
[하톡시그널] Retrofit으로 Nest.js와 통신하는 과정에서 있던 일.. (0) | 2021.11.21 |
[하톡시그널] Retrofit으로 서버와 연결하기 (0) | 2021.11.19 |