【Kotlin/Android】Jetpack Composeの使い方!UI実装方法
この記事からわかること
- Kotlin/Android Jetpack Composeの使い方
- 宣言的なUIの実装方法
- Composable関数と@Composableの使い方
- rememberで状態管理するには?
- @Previewの属性一覧
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Meerkat
- Kotlin:2.0.21
- AGP:8.9.2
- Gradle:8.11.1
- Mac M1:Sequoia 15.4
Jetpack Composeとは?
「Jetpack Compose」とはAndroidアプリ開発において宣言的にUIを実装できるUIツールキットです。AndroidアプリでのUI実装といえばXMLレイアウトファイルを使用して実装するイメージがあるかも知れませんが、それに変わるUI実装の方法として「Jetpack Compose」を使用した方法があります。
「Android Studio Koala」でプロジェクトを立ち上げると「build.gradle.kts(Module: app)」のdependencies内にlibs.androidx.activity.composeなど既にJetpack Composeが導入されていることが確認できます。
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
// Composeと連携するActivityの拡張ライブラリ(ActivityでComposeを使うため)
implementation(libs.androidx.activity.compose)
// ComposeのBOM(Bill of Materials)でバージョン管理を一括で行う
implementation(platform(libs.androidx.compose.bom))
// Compose UIのコアライブラリ(基本的なUI要素)
implementation(libs.androidx.ui)
// Composeの描画やグラフィック関連のライブラリ
implementation(libs.androidx.ui.graphics)
// Composeプレビュー機能のためのツールライブラリ
implementation(libs.androidx.ui.tooling.preview)
// Material3デザインコンポーネントのCompose版ライブラリ
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
// Compose BOMをテストにも適用
androidTestImplementation(platform(libs.androidx.compose.bom))
// Compose UIのJUnit4連携テストライブラリ
androidTestImplementation(libs.androidx.ui.test.junit4)
// Compose UIのデバッグツール(プレビューなどで使う)
debugImplementation(libs.androidx.ui.tooling)
// UIテスト時のマニフェスト関連のデバッグ用ライブラリ
debugImplementation(libs.androidx.ui.test.manifest)
}
Jetpack Composeの使い方自体は公式のチュートリアルなどが参考になるのでチェックしてみてください。
公式リファレンス:Jetpack Compose チュートリアル
公式リファレンス:Jetpack Compose の基本
既存プロジェクトへ導入する(Groovy DSL)
AndroidView(XMLレイアウト)でUIを実装していたプロジェクトに対し、Composeを導入する手順もまとめていきます。「build.gradle」もGroovy DSLの想定です。
Kotlin2以降からはCompose Compiler Gradleで管理する必要があるようです。それも含めてビルドに必要なライブラリなども全て導入していきます。
plugins {
// 追加
id "org.jetbrains.kotlin.plugin.compose" version "2.1.10" apply false
}
plugins {
id "org.jetbrains.kotlin.plugin.compose"
}
android {
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.8.3"
}
}
dependencies {
// Composeの基本UIコンポーネント(ボタンやテキストなど)
implementation "androidx.compose.ui:ui:1.8.3"
// Material Design 3(M3)のCompose対応ライブラリ
implementation "androidx.compose.material3:material3:1.3.2"
// Composeのプレビュー表示やツール向けサポートライブラリ
implementation "androidx.compose.ui:ui-tooling-preview:1.8.3"
// ActivityでComposeを使うための統合サポートライブラリ
implementation "androidx.activity:activity-compose:1.10.1"
// Composeの状態管理やランタイムのコアライブラリ
implementation "androidx.compose.runtime:runtime:1.8.3"
}
Jetpack Composeの使い方
実際に宣言的にUIを実装できるJetpack Composeの使い方を見ていきます。プロジェクトを立ち上げた際にデフォルトで実装されているコードをベースに読み解いてみます。
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.amefure.testcomposeapp.ui.theme.TestComposeAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Android 10以降でエッジ部分までコンテンツを描画する設定を有効化
enableEdgeToEdge()
// setContentでActivityとCompose UIを紐づけ
setContent {
// アプリ全体のテーマを適用(名称はアプリ名に依存)
// ui/Theme.kt に定義されている
TestComposeAppTheme {
// 基本レイアウトの枠組みを提供
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
// UI要素
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
}
// Composable関数であることを定義
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
// 文字列を画面に表示するためのComposeのコンポーネント
Text(
text = "Hello $name!",
modifier = modifier
)
}
// プレビュー
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
TestComposeAppTheme {
Greeting("Android")
}
}
このコードでビルドしてみると以下のような画面になります。
setContent
setContentブロックはActivityとCompose UIを紐づける役割を担っています。ブロックの中にComposable関数を記述することでViewツリー構造が構築されていく仕組みです。XMLレイアウトではsetContentView(R.layout.activity_main)のようにレイアウトファイルを指定してViewツリー構造を構築していたのと同じ役割です。
setContent { }
Composable関数
Composable関数とはJetpack ComposeにおけるUI部品となる関数のことです。Composable関数と定義するには@Composableアノテーションでマークする必要があります。Composable関数は内部でComposable関数を呼び出すことが可能です。
// Composable関数であることを定義
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
// 文字列を画面に表示するためのComposeのコンポーネント
Text(
text = "Hello $name!",
modifier = modifier
)
}
例えばTextはデフォルトで定義されているComposable関数であり様々な引数を受け取り見た目や挙動を制御することが可能になっています。
@Composable
fun Text(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
fontStyle: FontStyle? = null,
fontWeight: FontWeight? = null,
fontFamily: FontFamily? = null,
letterSpacing: TextUnit = TextUnit.Unspecified,
textDecoration: TextDecoration? = null,
textAlign: TextAlign? = null,
lineHeight: TextUnit = TextUnit.Unspecified,
overflow: TextOverflow = TextOverflow.Clip,
softWrap: Boolean = true,
maxLines: Int = Int.MAX_VALUE,
minLines: Int = 1,
onTextLayout: ((TextLayoutResult) -> Unit)? = null,
style: TextStyle = LocalTextStyle.current
)
デフォルトで定義されているComposable関数は色々ありボタン機能を持つButtonや背景を提供するSurfaceなど様々な種類があります。中にはColumnやBoxなど中に指定してComposable関数のレイアウトを制御するComposable関数もあります。
Button(
onClick = {
Log.d("Button", "Button Taped")
}
) {
Text("Button")
}
状態管理:remember
Jetpack Composeでは動的に変化する値(状態)を保持することが可能になっています。この仕組みを利用することで値の変化をそのままUIの変化に反映させることができるようになります。
状態を保持するためにはrememberブロックでmutableStateOfを囲んでプロパティを定義します。例えば以下のように実装することでボタンをクリックした際にテキストを入れ替えることができるようになります。
@Composable
fun Greeting(name: String) {
val expanded = remember { mutableStateOf(false) }
Surface(
color = MaterialTheme.colorScheme.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)
}
ElevatedButton(
onClick = { expanded.value = !expanded.value }
) {
Text(if (expanded.value) "Show less" else "Show more")
}
}
}
}
rememberの場合は画面が回転した場合などに保持していた状態がリセットされてしまうのでそれを防ぎたい場合はrememberSaveableを使用します。
プレビュー
Composable関数はプレビュー機能が使用できるようになっています。パラメータのないComposable関数またはデフォルトパラメータを渡したComposable関数に@Previewアノテーションを付与するだけでOKです。また1つのファイルに複数のプレビューを実装することも可能です。
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
TestComposeAppTheme {
Greeting("Android")
}
}
@Preview(
showBackground = true,
widthDp = 150,
heightDp = 150,
name = "Greeting Preview",
uiMode = Configuration.UI_MODE_NIGHT_MASK
)
@Composable
fun DarkThemePreview() {
TestComposeAppTheme {
Greeting("Android")
}
}
プレビューの表示はXMLレイアウトの時と同じように右上にある「Code」、「Split」、「Design」から「Split」、「Design」のどちらかを選択することで表示されるようになります。
またプレビューの右上くらいにカーソルを合わせて「Start Interactive Mode」をクリックするとプレビュー表示されているUIをタップなどの操作が可能になります。
@Previewの属性一覧
| 属性名 | 説明 |
|---|---|
| showBackground | UIの背景を表示するかどうか |
| widthDp | プレビューの幅(単位: dp)を指定 |
| heightDp | プレビューの高さ(単位: dp)を指定 |
| name | プレビュー名 |
| device | 特定のデバイスサイズでプレビューを表示 例:Devices.PHONE |
| uiMode | ダークモードやライトモードのプレビュー 例:Configuration.UI_MODE_NIGHT_YES |
| showSystemUi | ステータスバーやナビゲーションバーなど、システムUIもプレビューに表示するかどうか |
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。






