はじめに
AndroidのUI開発といえば、長らくXMLレイアウト + Activity/Fragmentという構成が一般的でした。 そこに登場したのがJetpack Compose。 宣言的UIに慣れ親しんだ身からすると、「やっとAndroidにも来たか…!」という気持ちになるツールキットです。
本記事では、Jetpack Composeをこれから触る人向けに、基本概念とシンプルな画面を作る手順をまとめます。
Composeとは
ざっくり言うと、宣言的にUIを構築するためのKotlin DSLです。 React/Flutterと近い発想で、「状態から画面を導出する」という考え方をします。
- XMLレイアウトが不要になる
@Composable関数を組み合わせてUIを作る- 状態が変わると、再描画が自動で起きる
プロジェクトのセットアップ
Android Studio(Flamingo以降推奨)で「Empty Compose Activity」を選ぶのがいちばん手軽です。
手動で設定する場合はbuild.gradle.ktsに以下を追加。
android {
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.3"
}
}
dependencies {
implementation("androidx.compose.ui:ui:1.5.4")
implementation("androidx.compose.material3:material3:1.1.2")
implementation("androidx.activity:activity-compose:1.8.0")
}
最初のComposable
@Composable
fun Greeting(name: String) {
Text(text = "Hello, $name!")
}
@Composableアノテーションがついた関数は、Composeの描画対象になります。
Activityからはこう呼び出します。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Greeting("World")
}
}
}
}
レイアウト基本:Column / Row / Box
FlutterでいうColumn/Row/Stackにあたるのがこれら。
@Composable
fun Profile() {
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Text("Taisei", style = MaterialTheme.typography.titleLarge)
Text("Mobile Engineer")
Row {
Button(onClick = {}) { Text("Follow") }
Spacer(Modifier.width(8.dp))
OutlinedButton(onClick = {}) { Text("Message") }
}
}
}
Modifierを使うと、パディング、背景色、クリック可能化などを関数チェーンで適用できます。
状態管理:rememberとmutableStateOf
状態を持たせたいときはrememberとmutableStateOfの組み合わせが基本です。
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Column {
Text("Count: $count")
Button(onClick = { count++ }) {
Text("Increment")
}
}
}
mutableStateOf:値の変更を検知できるStateを作るremember:再コンポーズされても値を保持するby:delegated propertyでcountを直接扱えるようにする
画面回転などの構成変更でも残したい場合はrememberSaveableを使います。
プレビュー機能
Composeの強みは、AndroidStudioで即座にプレビューできること。
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
MaterialTheme {
Greeting("Preview")
}
}
実機やエミュレータを起動せずに、UI調整が進められるので体験が一段階よくなります。
Material 3への対応
Android 12以降のDynamic Colorにも、Material 3コンポーネントを使えば比較的簡単に対応できます。
@Composable
fun MyAppTheme(content: @Composable () -> Unit) {
val context = LocalContext.current
val colors = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
dynamicLightColorScheme(context)
} else {
lightColorScheme()
}
MaterialTheme(colorScheme = colors, content = content)
}
おわりに
XMLの山からKotlin DSLへの移行は最初は戸惑いますが、慣れると圧倒的に書くのが楽しくなります。
既存プロジェクトへ段階的に取り入れる場合はComposeViewをXMLに埋め込めるので、新規画面から少しずつ移植するのがおすすめです。