Kotlin

Jetpack Composeでカスタムコンポーネントを作る方法とベストプラクティス

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

開発環境のセットアップとプロジェクト設定

Jetpack Compose で実務レベルのカスタムコンポーネントを作るには、安定版の開発ツールと依存関係を正しく構成することが最初のハードルです。本節では、2024 年時点で公式にリリースされている Android Studio と Compose のバージョンを前提に、IDE のインストール手順と Gradle/Kotlin の推奨設定を書き出します。

Android Studio のインストール(Flamingo 2023.1.1)

Android Studio Flamingo 2023.1.1 は公式ダウンロードページから取得できます。インストーラ実行後は次の項目にチェックを入れてください。

  • Android SDK – 最新プラットフォームとビルドツールが自動でインストールされます。
  • Jetpack Compose 用プラグイン – IDE が compose DSL を認識し、リアルタイムプレビューやコード補完が有効になります。

IDE 起動時に表示される「Welcome」画面の「Check for updates」を実行すれば、Kotlin 1.9 系と Compose Compiler 2.0 以降が自動的に適用された状態で作業できます。

Gradle と Kotlin のバージョン指定(推奨構成)

Compose 2024 系は Gradle 8.2 以上Kotlin 1.9.20 以上 が必要です。プロジェクトの settings.gradle.kts に以下を追記し、プラグインと Kotlin のバージョンを統一してください。

Compose BOM の導入とバージョン統一

BOM(Bill of Materials)を利用すると、Compose のすべてのモジュールが 同一バージョン で解決されるため、個別にバージョン番号を書き分ける手間が省けます。2024 年 6 月時点の最新 BOM は androidx.compose:compose-bom:2024.06.00 です。

BOM を使用すると、公式ドキュメントで推奨されているバージョン組み合わせと常に一致することが保証されます。

ポイント:Compose のプラグインやコンパイラのバージョンは Android Gradle Plugin が自動で管理しますので、個別に指定しない方が安全です。


@Composable とレイアウトモデルの基礎

この章では 「関数として UI を記述する」 という Compose の根本概念と、カスタムレイアウトを実装するときに必要な 測定(Measure)・配置(Layout) の流れを解説します。概念だけでなく、実際に手を書いたコード例も掲載しているので、すぐに試すことができます。

@Composable の基本構造

@Composable アノテーションは Kotlin コンパイラに対し「この関数は UI ツリーの一部になる」ことを指示します。以下は最小限のサンプルです。

  • 呼び出し側は Greeting("Compose") と書くだけで UI が生成されます。
  • 関数内部で状態が変化すると、Compose ランタイムが差分だけ再描画します(再コンポーズと呼ばれるプロセス)。

Measure・Layout パスの概要

カスタムレイアウトは Layout コンポーザブルを使って実装します。測定段階で子要素に サイズ要求 を伝え、配置段階で実際の座標を決める二段階プロセスです。

重要ポイントmeasurables.map { it.measure(constraints) } の結果は Placeable というオブジェクトになり、placeRelative(x, y) で配置します。

以下はシンプルな横並びレイアウト(Row 相当)です。コードのコメントに測定と配置のポイントを示しています。

この流れを理解すれば、円形メニューやマスグリッドなど 任意の幾何学的レイアウト を自前で実装できます。


状態管理とベストプラクティス

Compose では UI の再利用性は「状態(State)をどこに置くか」で決まります。ここでは remember / mutableStateOf と、派生状態を扱う derivedStateOf の正しい使い分けと、スコープ管理のコツを紹介します。

remember と mutableStateOf の役割

  • remember – コンポーズ関数が再実行されてもインスタンスを保持する。主にローカルな UI 状態で使用。
  • mutableStateOf – 変更可能な状態オブジェクト。by デリゲートと組み合わせて書くのが一般的。

注意:画面遷移や ViewModel で保持したい場合は rememberSaveablehiltViewModel() と併用し、プロセスが死んでも状態が失われないようにします。

derivedStateOf で計算コストを削減

派生状態は 元のステートが変化したときだけ再評価 されます。重い計算やリストフィルタリングに最適です。

  • heavyComputation が 10ms 程度かかる場合でも、input が変わらなければ再計算は走りません。
  • derivedStateOfスナップショットフロー と同様に Compose の再コンポーズサイクルに統合されるため、手動でキャッシュを管理する必要がありません。

スコープ最小化の実践例

以下はリスト項目ごとにローカル状態を持たせ、上位リスト全体の再描画を防ぐパターンです。

  • remember のスコープは TodoItem に限定され、リスト全体が再描画されてもこのアイテムだけは保持されます。

カスタムコンポーネントの作成手順

実務で再利用できる UI 部品を作る際に重要なのは API 設計Modifier の組み合わせ方 です。この章では、引数設計から Material3 テーマ継承、さらに独自 Layout 実装までのフローを具体例とともに示します。

関数シグネチャとパラメータ設計

必須情報(ビジネスロジック)とオプション設定(見た目・挙動)を分離し、デフォルト値で柔軟性を確保します。以下は「カード型ボタン」のサンプルです。

パラメータ 必須/任意 目的
textonClick 必須 ビジネスロジックの入口
modifier 任意 呼び出し側がサイズ・配置を上書きできる
enabled 任意 無効化時の UI/アクセシビリティ制御
backgroundColor 任意 テーマ外で色調整したいケース向け
contentPadding 任意 内部余白の微調整

Modifier の適用順序と注意点

Modifierチェーン可能 なオブジェクトです。実装時に順序を誤ると、期待しないレイアウトや描画結果になることがあります。以下は推奨される 「サイズ系 → 形状系 → 描画系 → 入力系」 の順序と、それぞれの代表的メソッドです。

カテゴリ 主な Modifier 効果例
サイズ系 fillMaxWidth(), height(), size() コンポーネントの外形寸法を決定
形状系 clip(), background() 角丸や背景色で見た目を整える
描画系 shadow(), border(), drawBehind{} 陰影、枠線、カスタム描画
入力系 clickable(), pointerInput{} , semantics{} タップ領域・アクセシビリティ情報

実装例(順序を意識したコード)

  • ポイントbackgroundclip の後に置くと、角丸が正しく適用された領域だけに色が付く。
  • clickable を最初に置くと、サイズが決まる前にヒットテストが走り、期待したタップ領域にならないことがあります。

Material3 テーマ・カラー・タイポグラフィの継承

Compose は スコープベース のテーマシステムを提供します。カスタムコンポーネント内部では MaterialTheme.colorSchemeMaterialTheme.typography に直接アクセスでき、アプリ全体のダークモード切替やカラーパレット変更に自動追従します。

  • MaterialThemeComposable 関数の呼び出し階層 に沿って継承されるため、テスト時にテーマだけ差し替えて UI の見た目を検証できます。

カスタム Layout 実装例(円形メニュー)

標準コンポーネントで実現できない配置は Layout コンポーザブルで自前のロジックを書きます。以下は「等間隔に配置した円形メニュー」の実装です。

  • 測定は子要素のサイズを取得し、配置では三角関数で円周上に座標変換しています。
  • radius.toPx() は Dp → ピクセル変換ユーティリティです(with(LocalDensity.current) { radius.toPx() } でも書けます)。

プレビュー・テスト・マルチプラットフォーム展開

Compose コンポーネントは 即時プレビュー自動 UI テスト が重要です。さらに、Kotlin Compose Multiplatform (KMP) で iOS や Web に流用する際の注意点もまとめます。

@Preview の活用方法と実装例

Android Studio Flamingo の「Compose Preview」ウィンドウは @Preview アノテーションだけで UI を描画します。デバイスサイズ・テーマ切替を同時に確認できるよう、複数のプレビューを一つの関数に付与します。

  • ポイントshowBackground = true を付けると、背景色が自動で描画され視認性が上がります。
  • 複数の @Preview を同一関数に貼ることで、デザインレビューの手間を大幅に削減できます。

Compose UI テストの基本フロー

UI テストは Compose のテストランナー (androidx.compose.ui:ui-test-junit4) と createComposeRule() で実装します。以下はボタンがクリックされたことを検証する最小サンプルです。

  • semanticsMatcher を併用すると、アクセシビリティ属性(contentDescription など)も同時に検証できます。
  • 同様のテストコードは KMP の sharedTest ソースセットでも利用可能です(androidMainiosMain 両方で実行できるよう設定すれば、プラットフォーム間でテストロジックを共有できます)。

Kotlin Compose Multiplatform での流用ポイント

Compose UI は 共通コード として Android・iOS・Web に展開可能ですが、プラットフォーム固有の API は expect/actual で分岐させます。以下に主な注意点をまとめました。

プラットフォーム 主な差分実装例 補足
iOS actual fun Modifier.clickable(onClick: () -> Unit) = this.then(ClickableModifier(onClick))(UIKit のタップジェスチャにブリッジ) 公式ライブラリ compose-uikit が提供する ComposeViewController をエントリポイントとして使用
Web actual fun Modifier.pointerHoverIcon(icon: Cursor) = this(HTML の cursor スタイルへ変換) compose-html / compose-web パッケージの Modifier.style { property("cursor", "pointer") } が代替手段
Desktop (JVM) 変更不要 – Android と同じ API が利用可能 Window コンポーネントでウィンドウサイズやメニューを制御

実務的なヒント:KMP プロジェクトでは UI のプレビューが Android Studio に限定されるため、iOS は Xcode シミュレータ・実機、Web は Chrome/Edge で手動確認するフローを CI に組み込むと品質が保てます。

パフォーマンス最適化チェックリスト

手法 実装上のポイント
remember のスコープ最小化 状態は可能な限りローカル @Composable に閉じ込め、上位関数での再描画を防ぐ
derivedStateOf の活用 高価な計算やフィルタリングは派生状態にキャッシュし、入力が変化したときだけ再評価
Lazy 系コンポーネント LazyColumn / LazyRow は表示領域外の項目を描画しないので、大量データでもスムーズ
key 指定で安定 ID items(key = { it.id }) とすると、リスト再配置時に状態が保持されアニメーションが滑らかになる
Modifier の順序最適化 サイズ系 → 形状系 → 描画系 → 入力系の順で書くと、無駄なレイアウト計算やヒットテストを回避できる

これらのベストプラクティスを組み合わせれば、Compose のデクララティブ特性を活かしつつ FPS 30+ を維持した快適 UI が実現できます。


まとめ

  • 開発環境:Android Studio Flamingo 2023.1.1、Gradle 8.2、Kotlin 1.9.20、Compose BOM 2024.06.00 を組み合わせると、公式が保証する安定構成で作業を開始できる。
  • @Composable の基礎:関数として UI を記述し、Measure‑Layout パスを理解すれば任意のレイアウトロジックが実装可能になる。
  • 状態管理remembermutableStateOf でローカルステートを保持し、derivedStateOf で計算コストを抑える。スコープは最小限に保ち、ViewModel との連携は rememberSaveable や Hilt を活用する。
  • コンポーネント設計:必須パラメータとデフォルト Modifier を分離し、Material3 テーマを継承させることで再利用性とテーマ適応性が向上する。Modifier は サイズ → 形状 → 描画 → 入力 の順序でチェーンすると予期せぬレイアウトバグを防げる。
  • プレビュー・テスト:複数の @Preview でデバイス・テーマを網羅し、Compose UI テストでクリックやアクセシビリティ属性を検証する。KMP の共有テストコードに組み込めば iOS/Web でも同様の品質基準が保てる。
  • マルチプラットフォーム:共通 UI は compose.ui 系でそのまま流用でき、iOS と Web は expect/actual による差分実装と公式ライブラリ(compose-uikit・compose-web)を組み合わせて対応。

以上の手順とベストプラクティスに従えば、公式ドキュメント通りかつ実務で即戦力となるカスタムコンポーネント を作成でき、プロジェクト全体の UI 品質向上につながります。ぜひ本記事をリファレンスとして、あなたのアプリに合わせた独自部品開発に挑戦してください。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Kotlin