Jetpack Compose:概要、主要概念、Composable関数

著者: IT Sectr 公開日: 2026-05-01 読了時間: 9 分

Jetpack Composeは、KotlinでAndroidインターフェースを構築するためのモダンな宣言型ツールキットです。開発者はcomposable関数を通じてUIを記述し、ツールキットは変更された部分のみを自動的に再描画します。Android Developers (2026)によると、Jetpack ComposeはAndroid 5.0(API 21)以上で動作し、Material Design 3をサポートし、ミッドレンジデバイスで120 FPSを達成します。これは独自のRecompositionシステム(変更されたウィジェットのみを更新するスマートなdiffアルゴリズム)によるものです。

主要ポイント

  • Jetpack Compose — Android向けの宣言型UIフレームワーク。Kotlinの@Composableアノテーション付き関数でインターフェースを構築。
  • Recomposition — データが変更されたコンポーネントのみを自動更新するメカニズム。120 FPSを実現。
  • StateはmutableStateOf、collectAsState、StateFlowで管理。値が変わると依存するビューのコンポジションが再開。
  • Modifier — クラス継承なしでパディング、サイズ、背景、クリック、アニメーションを設定する関数チェーン。
  • Side Effects — LaunchedEffect、DisposableEffect、rememberCoroutineScope — タイマー、ネットワークリクエスト、サブスクリプションなどの副作用を管理。

Jetpack Composeとは?

Jetpack Composeは、Googleが2019年に発表し2021年に安定版リリースを迎えた、Androidユーザーインターフェース構築のための宣言型フレームワークです。古いView System(XMLレイアウト+Activity/Fragment)とは異なり、Composeはアノテーション付きのKotlin関数(@Composable)を使用します。インターフェースはすべてKotlinで記述され、XMLとコードの分離はありません。これにより、XMLとKotlinのID不一致に関連するエラーが排除されました(type-safe syntheticはリファクタリング時に役立ちませんでした)。

Composeは独自のレンダリングシステムCanvas上に構築されており、View階層に依存しません。各ComposableはView SystemのonMeasure/onDrawをバイパスして、Canvasに直接描画します。これにより複雑な画面でのパフォーマンスが向上します:Googleのテスト(2023年)では、200要素のCompose画面はRecyclerView+ViewHolderの同様の画面より40%高速にレンダリングされました。

最小要件と互換性

ComposeにはminSdk 21(Android 5.0)とKotlin 1.9+が必要です。Compose BOM(Bill of Materials)がすべてのComposeライブラリのバージョンを同期します。このフレームワークは既存のView Systemコードと互換性があります:ComposeはComposeViewを介してXMLレイアウトに埋め込まれ、古いViewはAndroidViewを介してCompose階層に埋め込まれます。Google Play Console(2025年)によると、Android 5.0+はアクティブデバイスの97%をカバーしており、ほとんどのプロジェクトで互換性は制限になりません。

Composable関数とコンポジション

@Composableは、通常のKotlin関数をUI構成要素に変換するアノテーションです。Composable関数は、インターフェースの一部(テキスト、ボタン、リスト)がどのように見えるかを記述します。値を返す代わりに、関数はコンポジションにUIコンポーネントを出力(emit)します。これはジェネレーターに似ており、各関数は呼び出されると画面に要素を追加します。

kotlin
@Composable
fun ProfileCard(name: String, avatarUrl: String) {
    Card(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.surface
        )
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            AsyncImage(
                model = avatarUrl,
                contentDescription = "アバター",
                modifier = Modifier.size(48.dp).clip(CircleShape)
            )
            Spacer(Modifier.width(12.dp))
            Text(
                text = name,
                style = MaterialTheme.typography.titleMedium
            )
        }
    }
}

ProfileCard関数はパラメータ(name、avatarUrl)を受け取り、Card → Row → AsyncImage + Textを出力します。コンポジションは、1回のパスで出力されたコンポーネントのツリーです。パラメータが変更されていない場合、Composeは関数呼び出しをスキップします(recomposition skip)。nameのみが変更された場合、Textのみが呼び出され、残りの要素は再描画されません。このインテリジェントな再コンポジションは、手動のView System最適化に対するComposeの主要なパフォーマンス上の利点です。

スロットとContent Lambda

Composable関数はスロット(trailing lambda、content: @Composable (() -> Unit))を積極的に使用します。これにより、Card、Column、Rowなどのコンテナを作成でき、コンテンツはスロットに埋め込まれます。Slot APIはandroid:layout_gravityのようなXML属性を置き換えました。子要素の配置はコンテンツブロック内のKotlinコードで設定されるようになりました。

Composeでの状態管理

Composeにおける状態(State)とは、時間とともに変化する可能性のある値のことです。状態が変わると、Composeはその状態を読み取っているすべてのコンポーネントの再コンポジションをスケジュールします。この仕組みはReact hooksに似ています:mutableStateOfMutableState<T>を返し、.valueを読み取ると、現在のコンポジションが自動的に変更を購読します。

kotlin
@Composable
fun CounterExample() {
    var count by remember { mutableStateOf(0) }

    Column(modifier = Modifier.padding(16.dp)) {
        Text("クリックされました: $count")
        Button(onClick = { count++ }) {
            Text("増やす")
        }
    }
}

@Composable
fun UserScreen(viewModel: UserViewModel) {
    val userName by viewModel.userName.collectAsState()
    Text("ユーザー: $userName")
}

rememberは再コンポジション間で値を保持します。そうでなければ、UIが更新されるたびにmutableStateOfが新しく作成されます。collectAsState()はViewModelのStateFlowをCompose互換の状態に変換します。推奨事項 — 画面レベルの状態にはViewModelとStateFlowを、ローカル状態(展開されたカードなど)にはmutableStateOfを使用します。この分離はスマート/ダムコンポーネントの原則に従います。

State Hoisting(状態の引き上げ)

State Hoistingは、子コンポーネントから親コンポーネントに状態を引き上げるパターンです。親はパラメータを介して値とコールバックを渡し、子は変更時にコールバックを呼び出します。親がmutableStateOfを保持し、子はパラメータのみを保持します。これによりコンポーネントが再利用可能かつテスト可能になります。同じTextFieldを任意のデータソースで使用できます。

Modifier — 外観のカスタマイズ

Modifierは、Composableの変換(サイズ、パディング、背景、クリック処理、アニメーション、スクロール)を記述するオブジェクトです。モディファイアは呼び出しチェーンで適用されます:Modifier.fillMaxWidth().padding(16.dp).background(Color.Blue).clickable { }。各呼び出しはプロパティが追加された新しいModifierを返します。元のオブジェクトは変更されません。

モディファイアの順序は重要です。Modifier.padding(16.dp).background(Color.Blue)はパディング付きの領域を塗りつぶします。Modifier.background(Color.Blue).padding(16.dp)は内側の長方形を塗りつぶし、パディングは透明のままです。仕組みはCSSボックスモデルに似ています:paddingを先に→backgroundはmargin+backgroundのように機能。backgroundを先に→paddingはbackground+内部パディングのように機能。開発者は次のことを覚えておけば十分です:paddingを先に=外部マージン、paddingを後に=内部パディング。

カスタムモディファイア

組み込みのモディファイアで不十分な場合、Modifier.composed { ... }またはModifier.then()でカスタムモディファイアを作成します。カスタムモディファイア内では、レイアウト測定(Modifier.layout { measurable, constraints -> ... })、描画(Modifier.drawWithContent { ... })、ジェスチャー(Modifier.pointerInput { ... })を使用できます。例:クリック時のパルスアニメーション用モディファイア — サイズを測定し、クリック時にanimateFloatAsStateでスケールアニメーションを開始します。

アニメーション用に、Composeはanimate*AsState(animateFloatAsState、animateColorAsState、animateDpAsState)を提供します。変更時に値が古い状態と新しい状態の間でアニメーションします。出入りアニメーションにはAnimatedVisibilityAnimatedContentに組み込みのトランジション(フェード、スライド、展開)があります。すべてのアニメーションはグラフィックスレイヤーで動作し、不要なコンポジションをトリガーしません。

Side Effects: LaunchedEffect、DisposableEffect、remember

Composable関数は直接副作用(ネットワークリクエスト、タイマー、サブスクリプション)を実行すべきではありません。毎回の再コンポジションで呼び出されるため、リクエストが重複します。副作用のために、ComposeはEffect関数ファミリーを提供します:LaunchedEffectはコンポジションへの入場時にコルーチンを開始し、退場時にキャンセルします。DisposableEffectは明示的なクリーンアップが必要なリソース(センサー、BroadcastReceiver)用です。

kotlin
@Composable
fun SensorReader() {
    val context = LocalContext.current
    var sensorValue by remember { mutableStateOf(0f) }

    DisposableEffect(Unit) {
        val sensor = registerSensorListener(context) { value ->
            sensorValue = value
        }
        onDispose {
            unregisterSensorListener(sensor)
        }
    }

    Text("値: $sensorValue")
}

@Composable
fun UserGreeting(userId: String) {
    LaunchedEffect(userId) {
        val profile = api.fetchProfile(userId)
        // 状態更新
    }
}

LaunchedEffect(userId)はuserIdが変わると再起動します。前のコルーチンはキャンセルされ、新しいuserIdで新しいコルーチンが開始されます。これにより手動のリクエストキャンセル管理が不要になります。DisposableEffect(Unit) — 固定キーUnitを持つエフェクトで、コンポジション入場時に発火し、退場時にonDisposeを呼び出します。SensorReaderはリスナーを登録し、画面離脱時に購読を解除 — リークのリスクなし。

rememberCoroutineScope

コンポジション入場時ではなく、イベント(ボタンクリック)でコルーチンを起動する必要がある場合は、rememberCoroutineScope()を使用します。Composableのライフサイクルに紐づいたCoroutineScopeを返し、DisposableEffectは不要です。例:ボタンクリックでネットワークリクエストを開始 — scope.launch { viewModel.loadData() }。

Jetpack Compose vs View System:比較

ComposeとView Systemの選択は、2026年のAndroid開発者にとって主要なアーキテクチャ上の問題です。両方のテクノロジーはGoogleによってサポートされていますが、ComposeがGoogleがリソースを投じる主要な方向性です。View Systemは重要な修正のみを受け取り、進化していません。違いは構文、状態管理、パフォーマンス、開発時間に現れます。

側面Jetpack ComposeView System
UIの記述Kotlin @Composable関数XMLレイアウト+Activity/Fragment
状態mutableStateOf、StateFlow、自動再描画findViewById、手動:setText、notifyDataSetChanged
パフォーマンスインテリジェントな再コンポジション、CanvasレンダリングView階層、measure/layout/draw
アニメーションanimate*AsState、AnimatedVisibility、組み込みValueAnimator、ObjectAnimator、Transition
互換性minSdk 21、ComposeView/AndroidViewブリッジすべてのバージョン、任意
APKサイズComposeで+3–5 MBオーバーヘッドなし

新しいプロジェクトでは、GoogleはJetpack ComposeをUI開発の標準として推奨しています。View Systemは2021年以前に書かれたコードの保守と、APKサイズを最小限に抑える必要がある場合(例えば、エントリーレベルのデバイス向け新興市場)に残っています。Composeは宣言型構文と組み込みアニメーションのおかげで、View Systemと比較してUIコード量を30〜50%削減します。

よくある質問

既存のView SystemプロジェクトでComposeを使用できますか?

はい、XMLレイアウトのComposeViewを介して可能です。Composeの依存関係を追加し、画面またはその一部をComposeView { MyComposable() }でラップします。移行は画面ごとに行います。

Composableが頻繁に再描画されるのはなぜですか?

原因は、状態が高く引き上げられすぎているか、変更可能なオブジェクトが使用されていることです。修正:派生データにはderivedStateOf、安定した参照にはrememberを使用します。

Composeでリストを実装するには?

LazyColumn(RecyclerViewに類似)を使用します。スクロールに応じて要素が作成および再利用されます。異なるセルタイプの複雑なリストの場合 — LazyColumn { items(items, key = { it.id }) { ... } }

Composeの前にView Systemを学ぶ必要がありますか?

いいえ、Composeから直接始められます。View Systemの知識はレガシーコードの保守に役立ちますが、Composeは独自のドキュメントとパターンを持つ独立したエコシステムです。

ComposeはMaterial 3をサポートしていますか?

はい、Material 3は2023年からComposeの標準テーマです。implementation("androidx.compose.material3:material3")で追加します。Material 2は非推奨と見なされています。

まとめ

  • Jetpack Compose — Android向け宣言型UIフレームワーク。インターフェース全体を@Composable関数でKotlinに記述。
  • Recompositionは変更されたコンポーネントのみを自動再描画し、手動最適化なしで120 FPSを実現。
  • StateはmutableStateOf、collectAsState、StateFlowで管理。State Hoistingパターンでコンポーネントを再利用可能に。
  • Modifier — クラス継承なしで外観、アニメーション、動作を設定する変換チェーン。
  • Side Effects(LaunchedEffect、DisposableEffect)は副作用を再コンポジションから分離し、リークとリクエスト重複を防止。
  • LazyColumnはより少ないコードでRecyclerViewを置き換え、AnimatedVisibilityは複雑なAnimatorチェーンを置き換え。
  • Googleはすべての新規プロジェクトにComposeを推奨。View SystemはレガシーコードとAPKサイズが重要な場合に残る。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください