Jetpack Composeに馴染みたい

公開日: 2021年03月02日最終更新日: 2022年01月28日

なにやら最近、Jetpack Composeが盛り上がってきています。

Compose の思想に以下のようにあります。

"Compose is a declarative UI framework."

Jetpack Composeは宣言的UIフレームワークです。Reactみたいな感じですかね。
Androidでも、実現したいUIとコードが対応する形で記述できるようになりました。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp {
                MyScreenContent()
            }
        }
    }
}

@Composable
fun MyApp(content: @Composable () -> Unit) {
    ComposeStudyTheme {
        Surface(color = Color.Yellow) {
            content()
        }
    }
}

@Composable
fun Greeting(name: String) {
    var isSelected by remember { mutableStateOf(false) }
    val backgroundColor by animateColorAsState(if (isSelected) Color.Red else Color.Transparent)
    Text(
        text = "Hello $name!",
        modifier = Modifier
            .padding(24.dp)
            .background(color = backgroundColor)
            .clickable(onClick = { isSelected = !isSelected })
    )
}

@Composable
fun Counter(count: Int, updateCount: (Int) -> Unit) {
    Button(
        onClick = { updateCount(count + 1) },
        colors = ButtonDefaults.buttonColors(
            backgroundColor = if (count > 5) Color.Green else Color.White
        )
    ) {
        Text("I've been clicked $count times")
    }
}

@Composable
fun NameList(names: List<String>, modifier: Modifier = Modifier) {
    LazyColumn(modifier = modifier) {
        items(items = names) { name ->
            Greeting(name = name)
            Divider(color = Color.Black)
        }
    }
}

@Composable
fun MyScreenContent(names: List<String> = List(1000) { "HelloAndroid #$it" }) {
    val counterState = remember { mutableStateOf(0) }
    Column(modifier = Modifier.fillMaxHeight()) {
        NameList(names = names, modifier = Modifier.weight(1f))

        Counter(
            count = counterState.value, updateCount = { newCount ->
                counterState.value = newCount
            })
    }
}

こんな感じです。

今までは、

  • xmlでUIを定義して、findViewById()を使ってツリーをたどり、各Viewのメソッドを呼び出して更新していた。
  • Viewをメソッドで操作するとバグにつながる。
  • 一部の更新を忘れたり、更新の競合によって不正な状態になったりするなどバグにつながる。

だったのが、Jetpack Composeを使うことで、

  • 宣言的UIにして欲しいUIをそのままコードで定義できるようにした。
  • 状態を持つビューを個別に手動で更新しなくて良くなる(データだけ更新すればいい)。
  • Kotlinで書かれるのでfor文で回して動的に要素を生成できる
  • 再描画する必要がある部分だけを再コンポーズしてくれる。

という感じでしょうか。

参考リンク

追伸

全然関係ないですけど、よつばとの15巻がでましたね。 よつばが小学校に通いだしたらクラスメートとか登場人物増えるんだろうか。