compose-sample을 보면서 compose를 공부하는 것 좋다. 하지만 샘플을 보고, 내가 블로깅하려는 내용을 선정하는 것에 리소스가 생기는 것을 방지하고자, codelab-android-compose을 통해 기본적인 사안만을 빠르게 다루고자하는 내용을 정하고자 한다.
BasicsCodelab을 살펴보도록 하겠다.
가이드 화면 이후, 버튼을 눌러 가이드 화면 여부를 체킹하여 리스트를 보여주는 간단한 앱이다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BasicsCodelabTheme {
MyApp(modifier = Modifier.fillMaxSize())
}
}
}
BasicsCodelabTheme라는 설정한 기본 테마를 입혀 MyApp이라는 Composable을 화면 가득하다는 modifier를 파라미터로 전달했다.
@Composable
fun MyApp(modifier: Modifier = Modifier) {
var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) }
Surface(modifier, color = MaterialTheme.colorScheme.background) {
if (shouldShowOnboarding) {
OnboardingScreen(onContinueClicked = { shouldShowOnboarding = false })
} else {
Greetings()
}
}
}
MyApp은 modifier를 파라미터로 받고 있고, 온보딩 화면을 보여줘야하는지 여부를
var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) }
를 통해 관리하여 다음 화면을 분기하고 있다. 이 때 사용된 rememberSaveable은 recomposition이라는 compose의 특성과 연관 있으며, recomposition이 발생하여 UI를 업데이트할 때에도 보존하고자 하는 것을 정의한다.
@Composable
fun OnboardingScreen(
onContinueClicked: () -> Unit,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Welcome to the Basics Codelab!")
Button(
modifier = Modifier.padding(vertical = 24.dp),
onClick = onContinueClicked
) {
Text("Continue")
}
}
}
@Composable
private fun Greetings(
modifier: Modifier = Modifier,
names: List<String> = List(1000) { "$it" }
) {
LazyColumn(modifier = modifier.padding(vertical = 4.dp)) {
items(items = names) { name ->
Greeting(name = name)
}
}
}
Column을 통해 화면의 레이아웃을 선언했고, onContinueClicked로 클릭 이벤트의 결과를 파라미터로 넘겨주고 있음을 확인할 수 있다.
버튼이 클릭되면, OnboardingScreen(onContinueClicked = { shouldShowOnboarding = false })에서 설정한 shouldShowOnboarding이 false가 된다.
그리고 Greetings 화면으로 이동한다.
LazyColumn을 통해 구현 시 설정한 리스트로 목록을 그리고, modifier로 padding 값을 설정하고 있다.Greeting으로 하나하나의 아이템 뷰를 그린다.
@Composable
private fun Greeting(name: String) {
Card(
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.primary
),
modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp)
) {
CardContent(name)
}
}
Card로 아이템 뷰를 그리고, 아이템 뷰의 색상과 padding 값을 설정한다.
@Composable
private fun CardContent(name: String) {
var expanded by remember { mutableStateOf(false) }
Row(
modifier = Modifier
.padding(12.dp)
.animateContentSize(
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow,
),
),
) {
Column(
modifier = Modifier
.weight(1f)
.padding(12.dp),
) {
Text(text = "Hello, ")
Text(
text = name,
style = MaterialTheme.typography.headlineMedium.copy(
fontWeight = FontWeight.ExtraBold,
),
)
if (expanded) {
Text(
text = (
"Composem ipsum color sit lazy, " +
"padding theme elit, sed do bouncy. "
).repeat(4),
)
}
}
IconButton(onClick = { expanded = !expanded }) {
Icon(
imageVector = if (expanded) Filled.ExpandLess else Filled.ExpandMore,
contentDescription = if (expanded) {
stringResource(R.string.show_less)
} else {
stringResource(R.string.show_more)
},
)
}
}
}
expand로 아이템 뷰의 화살표가 클릭외었는지 여부를 저장하고, Row로 화살표가 있는 영역과 그외 영역을 horizontal하게 배치한다. 또한 expand로 화살표의 이미지를 결정한다.
확실히 이 프로젝트가 더 가볍기 때문에 처음 학습하기에 적당한 것 같다는 것이 느껴졌다.
다음 포스팅은 Basic layouts codelab 이다.