행과 열로 아이템 구성하기
Compose에 포함된 Column, Row, Box와 같은 표준 레이아웃 3요소가 있다.
Column, Row, Box도 composable 함수다. 이 함수들은 다른 composable 요소들을 내부에서 각기 다른 형태로 배치 한다. 예를들어 다음과 같은 코드가 있다고 가정하자.
@Composable private fun Greeting(name: String) { Surface(color = MaterialTheme.colors.primary) { Column(modifier = Modifier.padding(24.dp)) { Text(text = "Hello,") Text(text = name) } } }
Column은 수직으로 각각의 항목을 배치하므로, 그 결과는 다음과 같다.
코틀린 문법과 Compose
composable 함수는 Kotlin의 문법을 기반으로 사용할 수 있다. 이러한 부분은 UI가 표시되는 방식에 코틀린 문법을 추가할 수 있으므로 UI 구축이 정말 강력해진다. 예를 들어 for 루프를 사용하여 Column 요소를 추가할 수 있다.
@Composable fun MyApp(names: List<String> = listOf("World", "Compose")) { Column { for (name in names) { Greeting(name = name) } } }
composable로 사이즈 수치를 지정하지 않았거나 제약조건을 추가하지 않았다면, 각 행의 아이템은 최소의 사이즈를 가지고 preview상에 나타나게 된다. 다음과 같이 widthDp 속성을 변경하여 가로 길이를 320dp로 지정해보자.
@Preview(showBackground = true, widthDp = 320) @Composable fun DefaultPreview() { BasicsCodelabTheme { MyApp() } }
Modifier는 Compose에서 광범위하게 사용된다. fillMaxWidth 와 padding을 사용하여 아래의 preview처럼 나타내보자.
코드의 변경사항을 확인해보자
@Composable fun MyApp(names: List<String> = listOf("World", "Compose")) { Column(modifier = Modifier.padding(vertical = 4.dp)) { for (name in names) { Greeting(name = name) } } } @Composable private fun Greeting(name: String) { Surface( color = MaterialTheme.colors.primary, modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp) ) { Column(modifier = Modifier.fillMaxWidth().padding(24.dp)) { Text(text = "Hello, ") Text(text = name) } } }
버튼 추가 하기
다음 단계로 Greeting을 확장하여 클릭할 수 있는 버튼을 추가해보자. 버튼을 추가하고나면 다음과 같은 레이아웃으로 구성될 것이다.
Button이라는 Composable 함수도 머테리얼 패키지로부터 제공된다. Button은 마지막 파라미터로 composable 함수를 갖는다. 코틀린 문법에 따르면, 함수의 마지막 파라미터가 함수일 경우 해당 인자로 전달된 람다 표현식을 괄호 밖에 배치 할 수 있다. 이를 trailing lambda라고 한다. Button에 Text를 추가하는 예제를 살펴보자.
// 아직 복사 ㄴㄴ Button( onClick = { } // 콜백은 나중에~ ) { Text("Show less") }
Compose는 머테리얼 디자인 버튼 스펙에 따르면 다양한 버튼 타입을 제공하고 있다.
- Button
- OutlinedButton
- TextButton
이 중 OutlinedButton을 사용하여 Text를 감싸는 Button을 만들어보자.
이것을 구현하려면 행(Row)의 마지막 아이템을 배치하는 방법에 대해서 알아야 한다. Modifier에는 alignEnd 같은 속성은 존재 하지 않는다. 대신에 시작하는 composable에 weight를 적용할 수 있다. weight는 composable이 배치되는 남는 공간을 전부 채우게 한다. LinearLayout의 weight와 비슷하다고 보면 된다. weight를 사용하면 좀더 유연하고 효과적으로 다른 weight가 없는 composable들을 밀어낼 수 있다. 그로인해 fillMaxWidth 속성은 여기서 쓸모 없어지게 되므로 기존 코드에서 제거하자.
@Composable private fun Greeting(name: String) { Surface( color = MaterialTheme.colors.primary, modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp) ) { Row(modifier = Modifier.padding(24.dp)) { Column(modifier = Modifier.weight(1f)) { Text(text = "Hello, ") Text(text = name) } OutlinedButton( onClick = { /* TODO */ } ) { Text("Show more") } } } }
0개의 댓글