Android Compose 튜토리얼 | Android 개발자 | Android Developers
Jetpack Compose는 네이티브 Android UI를 빌드하기 위한 최신 도구 키트입니다. Jetpack Compose는 더 적은 수의 코드, 강력한 도구, 직관적인 Kotlin API로 Android에서의 UI 개발을 간소화하고 가속화합니다. 이
developer.android.com
Lesson 4: Lists and animations
Create a list of messages
LazyColumn과 LazyRow는 화면에 표시되는 요소만 렌더링하여 긴 리스트에 효율적으로 디자인
LazyColumn은 하위 요소 items는 List를 매개변수로 취하고, 람다는 제공된 List의 아이템마다 호출
// ...
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
@Composable
fun Conversation(messages: List<Message>) {
LazyColumn {
items(messages) { message ->
MessageCard(message)
}
}
}
@Preview
@Composable
fun PreviewConversation() {
ComposeTutorialTheme {
Conversation(SampleData.conversationSample) // SampleData: https://gist.github.com/yrezgui/26a1060d67bf0ec2a73fa12695166436
}
}
Animate messages while expanding
애니메이션에 필요한 상태를 저장하기 위해 remember와 mutableStateOf를 사용해야 함
- remember: Composable function의 로컬 상태를 메모리에 저장
- mutableStateOf: 전달된 로컬 상태 값의 변화를 추적
Composable과 하위 요소들은 값이 업데이트 될 때마다 자동으로 다시 그려짐(recomposition, 재구성)
// ...
import androidx.compose.foundation.clickable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTutorialTheme {
Conversation(SampleData.conversationSample)
}
}
}
}
@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
)
}
}
}
}
clickable modifier를 사용해 click event 제어 가능
animateColorAsState: 애니메이션을 적용하여 자연스럽게 색상 변경
animateContentSize: 애니메이션을 적용하여 자연스럽게 container 크기 변경
// ...
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize
@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 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
)
}
}
}
}
지금까지 배운 내용
- 구성 가능한 함수 정의
- 컴포저블에 다른 요소 추가
- 레이아웃 컴포저블을 사용하여 UI 구성요소 구조화
- 수정자를 사용한 컴포저블 확장
- 효율적인 목록 만들기
- 상태 추적 유지 및 수정
- 컴포저블에 사용자 상호작용 추가
- 메시지 확장 중 메시지에 애니메이션 적용
'Android App > Jetpack' 카테고리의 다른 글
[Compose/Course] Compose Overview (0) | 2022.08.26 |
---|---|
[Compose/Course] Tutorial: Jetpack Compose basics - #3 Material Design (0) | 2022.08.25 |
[Compose/Course] Tutorial: Jetpack Compose basics - #2 Layouts (0) | 2022.08.24 |
[Compose/Course] Tutorial: Jetpack Compose basics - #1 Composable functions (0) | 2022.08.24 |