— Android, Jetpack — 2 min read
1@Composable2fun MyApp(names: List<String> = listOf("World", "Compose")) {3 Column {4 for (name in names) {5 Greeting(name = name)6 }7 }8}
Compose는 선언형이기 때문에 값을 바꾸기 위해서는 Compose함수에 다른 값을 전달하는 방법 뿐이다. 보통 이 값을 UI State라고 한다. State가 업데이트 될 때 마다, recompositon이 수행된다. TextField같은 위젯은 xml과 달리 스스로 값을 업데이트하지 않는다. Composable은 명시적으로 state가 바뀌었음을 알려줘야 업데이트가 일어난다.
Composable 에서는 remember라는 것을 이용해서 상태 값을 관리할 수 있다. remember는 mutable 또는 immutable 객체로 사용가능하다.
1val mutableState = remember { mutableStateOf(default) }
Flutter에서 사용되는 StatefulWidget과 StatelessWidget과 유사한 개념이다. 상태가 있는 곳에서는 값을 바꾸거나 상태를 기억할 수 있고, 상태가 존재하지 않는 곳에서는 값을 바꾸거나 상태를 기억하지 못한다.
Compose에서 remeber로 상태를 관리하고, 기억하는 것은 Stateful, 즉 상태를 가지는 위젯이다. Stateless 위젯은 어떠한 상태도 가지지 않는 위젯을 뜻한다.
1@Composable2fun Text(3 text: String,4 modifier: Modifier = Modifier,5 color: Color = Color.Unspecified,6 fontSize: TextUnit = TextUnit.Unspecified,7 fontStyle: FontStyle? = null,8 fontWeight: FontWeight? = null,9 fontFamily: FontFamily? = null,10 letterSpacing: TextUnit = TextUnit.Unspecified,11 textDecoration: TextDecoration? = null,12 textAlign: TextAlign? = null,13 lineHeight: TextUnit = TextUnit.Unspecified,14 overflow: TextOverflow = TextOverflow.Clip,15 softWrap: Boolean = true,16 maxLines: Int = Int.MAX_VALUE,17 onTextLayout: (TextLayoutResult) -> Unit = {},18 style: TextStyle = LocalTextStyle.current19) {20 Text(21 AnnotatedString(text),22 modifier,23 color,24 fontSize,25 fontStyle,26 fontWeight,27 fontFamily,28 letterSpacing,29 textDecoration,30 textAlign,31 lineHeight,32 overflow,33 softWrap,34 maxLines,35 emptyMap(),36 onTextLayout,37 style38 )39}
1Text(2 text = "${message.body}",3 style = MaterialTheme.typography.body2,4 modifier = Modifier.padding(all = 4.dp),5 color = MaterialTheme.colors.secondaryVariant6 )
1@Composable2inline fun Column(3 modifier: Modifier = Modifier,4 verticalArrangement: Arrangement.Vertical = Arrangement.Top,5 horizontalAlignment: Alignment.Horizontal = Alignment.Start,6 content: @Composable ColumnScope.() -> Unit7) {8 val measurePolicy = columnMeasurePolicy(verticalArrangement, horizontalAlignment)9 Layout(10 content = { ColumnScopeInstance.content() },11 measurePolicy = measurePolicy,12 modifier = modifier13 )14}
1@Composable2fun LazyList() {3 // We save the scrolling position with this state that can also 4 // be used to programmatically scroll the list5 val scrollState = rememberLazyListState()6
7 LazyColumn(state = scrollState) {8 items(100) {9 Text("Item #$it")10 }11 }12}
1@Composable2fun MessageCard(msg: Message) {3 Column {4 Text(text = msg.author)5 Text(text = msg.body)6 }7}
1@Composable2inline fun Row(3 modifier: Modifier = Modifier,4 horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,5 verticalAlignment: Alignment.Vertical = Alignment.Top,6 content: @Composable RowScope.() -> Unit7) {8 val measurePolicy = rowMeasurePolicy(horizontalArrangement, verticalAlignment)9 Layout(10 content = { RowScopeInstance.content() },11 measurePolicy = measurePolicy,12 modifier = modifier13 )14}
1fun Modifier.customLayoutModifier(...) = Modifier.layout { measurable, constraints ->2 ...3})
dependency 추가
1// build.gradle2implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-alpha07"
1@Composable2fun ConstraintLayoutContent() {3 ConstraintLayout {4
5 // Create references for the composables to constrain6 val (button, text) = createRefs()7
8 Button(9 onClick = { /* Do something */ },10 // Assign reference "button" to the Button composable11 // and constrain it to the top of the ConstraintLayout12 modifier = Modifier.constrainAs(button) {13 top.linkTo(parent.top, margin = 16.dp)14 }15 ) {16 Text("Button")17 }18
19 // Assign reference "text" to the Text composable20 // and constrain it to the bottom of the Button composable21 Text("Text", Modifier.constrainAs(text) {22 top.linkTo(button.bottom, margin = 16.dp)23 })24 }25}
1val barrier = createEndBarrier(button1, text)