Contents
1️⃣ 開発環境の準備
| 必要項目 | 推奨バージョン / 条件 |
|---|---|
| Android Studio | Flamingo (2023.3.1) 以降 – AGP 8.2 系に対応し、Compose Preview・Live Edit が安定動作します。 ※ Flamingo の次期リリースが出た場合は、同等以上のバージョンを選択してください。 |
| JDK | OpenJDK 17(Android Studio に同梱) |
| Kotlin プラグイン | 1.9.x 以上(Android Studio の「Settings → Plugins」から確認) |
| Android Gradle Plugin (AGP) | 8.2.x 以上 |
設定手順
- Android Studio のインストール
-
Android Developers 公式サイトのクイックスタートページから「Download Android Studio」ボタンをクリックし、Flamingo (2023.3.1) をダウンロードしてインストールします。
-
JDK の確認
-
File → Project Structure → SDK Locationで JDK が OpenJDK 17 になっていることを確認。IDE に同梱されていれば追加設定は不要です。 -
プラグインの有効化
File → Settings → Plugins→ 「Kotlin」・「Android Gradle Plugin」のバージョンが最新かチェックし、未導入なら Install で追加します。
ポイント:上記環境を整えるだけで、Compose プロジェクト作成時に起こりやすい互換性エラーはほぼ回避できます。
2️⃣ Compose プロジェクトの作成と依存関係管理
2‑1. 新規プロジェクトで Compose を有効化する手順
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
plugins { id "com.android.application" id "org.jetbrains.kotlin.android" } android { compileSdk = 34 defaultConfig { applicationId = "com.example.todo" minSdk = 21 targetSdk = 34 versionCode = 1 versionName = "1.0" } // Compose を有効にする buildFeatures { compose = true } // 現在の安定版コンパイラ拡張バージョン(2024 年 2 月時点) composeOptions { kotlinCompilerExtensionVersion = "1.6.0" } kotlinOptions { jvmTarget = "17" } } |
buildFeatures.composeに true を設定すると IDE が自動で Compose のビルドサポートを有効化します。composeOptions.kotlinCompilerExtensionVersionは公式 BOM と合わせるのがベストプラクティスです。
2‑2. Compose BOM(Bill of Materials)による依存関係一元管理
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
dependencies { // ★ 2024 年 2 月時点の最新 Compose BOM implementation platform('androidx.compose:compose-bom:2024.02.00') // UI 基本コンポーネント implementation "androidx.compose.ui:ui" implementation "androidx.compose.material3:material3" // Navigation(BOM に含まれるのでバージョン指定不要) implementation "androidx.navigation:navigation-compose" // デバッグ・プレビュー用 debugImplementation "androidx.compose.ui:ui-tooling" debugImplementation "androidx.compose.ui:ui-test-manifest" } |
- BOM を使うと、
androidx.compose:*系のすべてのライブラリが同一バージョンで揃えられ、個別にバージョン番号を管理する手間が省けます。 - バージョンは
platform(...)の行だけ更新すれば OK です。(実際の最新番号は公式ページで随時確認してください)
ポイント:BOM を導入したら、個別ライブラリにバージョンを付与しないよう注意。付けると BOM の意味が失われます。
3️⃣ Composable 関数の基本と State 管理
3‑1. 基本構文と @Preview の活用
|
1 2 3 4 5 6 7 8 9 10 11 |
@Composable fun Greeting(name: String) { Text(text = "Hello, $name!") } @Preview(showBackground = true, name = "Greeting Preview") @Composable fun GreetingPreview() { Greeting(name = "Compose") } |
@Previewに showBackground を付けると、薄いグレー背景が自動で描画され UI が見やすくなります。- Android Studio の Design タブで即座に結果が確認でき、コード変更がリアルタイムで反映されます。
3‑2. State(状態)管理のベストプラクティス
| API | 用途 | 主な特徴 |
|---|---|---|
remember { mutableStateOf(...) } |
UI スコープ内で一時的に保持する状態 | 再コンポジション時に値が失われない |
rememberSaveable { ... } |
画面回転やプロセス再起動でも永続化したい場合 | Bundle に自動保存(基本型・Parcelable が対象) |
derivedStateOf { … } |
他の State から派生する計算結果をキャッシュ | 再計算は依存が変わったときだけ |
カウンターサンプル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Composable fun Counter() { var count by rememberSaveable { mutableStateOf(0) } Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(16.dp) ) { Text(text = "Count: $count", style = MaterialTheme.typography.headlineMedium) Spacer(modifier = Modifier.height(8.dp)) Button(onClick = { count++ }) { Text("Increase") } } } |
rememberSaveableにより画面回転でも count が保持されます。
3‑3. アクセシビリティとテーマの基本
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Composable fun AccessibleButton( onClick: () -> Unit, label: String, modifier: Modifier = Modifier ) { Button( onClick = onClick, modifier = modifier.semantics { contentDescription = label } ) { Icon(Icons.Default.Add, contentDescription = null) Text(text = label) } } |
semanticsを付与すると TalkBack などの支援技術が正しく読み上げます。- アプリ全体は Material 3 テーマで統一し、
colorSchemeやtypographyをカスタマイズすればブランドカラーに合わせたデザインが実現できます。
ポイント:Compose は UI とロジックが同居するため、アクセシビリティ属性は忘れずに付与しましょう。
4️⃣ 画面遷移と実践的 Todo アプリの実装
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Composable fun TodoAppNavHost( navController: NavHostController = rememberNavController() ) { NavHost(navController, startDestination = "list") { composable("list") { TodoListScreen(navController) } composable( route = "detail/{todoId}", arguments = listOf(navArgument("todoId") { type = NavType.IntType }) ) { backStackEntry -> val id = backStackEntry.arguments?.getInt("todoId") ?: -1 TodoDetailScreen(todoId = id, navController = navController) } } } |
startDestinationが最初に表示される画面です。- パラメータは navArgument で型安全に取得できます。
4‑2. 完全版 Todo アプリ(主要コード)
MainActivity.kt
|
1 2 3 4 5 6 7 |
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { TodoAppNavHost() } } } |
TodoListScreen.kt
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
@Composable fun TodoListScreen(navController: NavHostController) { var todos by rememberSaveable { mutableStateOf(listOf<String>()) } var newTodoText by remember { mutableStateOf("") } Column( modifier = Modifier .fillMaxSize() .padding(16.dp) ) { // 入力エリア Row(verticalAlignment = Alignment.CenterVertically) { TextField( value = newTodoText, onValueChange = { newTodoText = it }, label = { Text("新しい Todo") }, modifier = Modifier.weight(1f) ) Spacer(modifier = Modifier.width(8.dp)) Button(onClick = { if (newTodoText.isNotBlank()) { todos = todos + newTodoText newTodoText = "" } }) { Text("追加") } } Spacer(modifier = Modifier.height(16.dp)) // Todo 一覧(LazyColumn) LazyColumn { itemsIndexed(todos, key = { index, _ -> index }) { index, item -> TodoItem( todo = item, onClick = { navController.navigate("detail/$index") }, onDelete = { todos = todos.toMutableList().also { it.removeAt(index) } }) } } } } |
TodoItem.kt(再コンポジション削減)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
@Composable fun TodoItem( todo: String, onClick: () -> Unit, onDelete: () -> Unit ) { // onDelete が変わらない限り同一インスタンスを保持 val deleteAction = remember(onDelete) { onDelete } Card( modifier = Modifier .fillMaxWidth() .padding(vertical = 4.dp) .clickable(onClick = onClick), elevation = CardDefaults.cardElevation(2.dp) ) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(12.dp) ) { Text(text = todo, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.weight(1f)) IconButton(onClick = deleteAction) { Icon(Icons.Default.Delete, contentDescription = "削除") } } } } |
TodoDetailScreen.kt
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
@Composable fun TodoDetailScreen(todoId: Int, navController: NavHostController) { // デモ用データ。実際は ViewModel から取得すべきです。 val todoText = remember { "Todo #$todoId の詳細" } Scaffold( topBar = { TopAppBar( title = { Text("Todo 詳細") }, navigationIcon = { IconButton(onClick = { navController.popBackStack() }) { Icon(Icons.Default.ArrowBack, contentDescription = "戻る") } }) } ) { innerPadding -> Box( modifier = Modifier .fillMaxSize() .padding(innerPadding), contentAlignment = Alignment.Center ) { Text(text = todoText, style = MaterialTheme.typography.headlineMedium) } } } |
4‑3. アーキテクチャ拡張のヒント
| 拡張ポイント | 推奨ライブラリ |
|---|---|
| 状態管理 | androidx.lifecycle:lifecycle-viewmodel-compose(ViewModel + Compose) |
| DI | Hilt (dagger:hilt-android) と hilt-navigation-compose |
| 永続化 | Room データベース + flow でリアクティブに UI に反映 |
ポイント:サンプルはシンプルさを重視していますが、実務では ViewModel にロジックを委譲し、テスト可能な構造へ段階的にリファクタリングしましょう。
5️⃣ デバッグ・パフォーマンス最適化、ビルド & デプロイ
5‑1. UI デバッグとプレビュー活用術
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class TodoPreviewProvider : PreviewParameterProvider<String> { override val values = sequenceOf( "買い物リスト", "仕事のタスク", "読書メモ" ) } @Composable @Preview(showBackground = true, name = "TodoItem 多パラメータ") fun TodoItemPreview(@PreviewParameter(TodoPreviewProvider::class) title: String) { Card(modifier = Modifier.padding(8.dp)) { Text(text = title, modifier = Modifier.padding(16.dp)) } } |
PreviewParameterProviderで 複数バリエーション を同時に確認でき、デザイン修正の手間が削減されます。- Live Edit が有効な状態(Flamingo 以上)ではコード変更 → プレビュー自動更新が即座に反映されます。
5‑2. 再コンポジション削減と Lazy コンポーネントのテクニック
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@Composable fun TodoItemOptimized( todo: String, onDelete: () -> Unit, modifier: Modifier = Modifier ) { // onDelete が変わらない限り同じラムダを再利用 val deleteClick = remember(onDelete) { onDelete } Row( modifier = modifier .fillMaxWidth() .padding(8.dp), verticalAlignment = Alignment.CenterVertically ) { Text(text = todo, modifier = Modifier.weight(1f)) IconButton(onClick = deleteClick) { Icon(Icons.Default.Delete, contentDescription = "削除") } } } |
rememberに渡すキーが変わらなければ ラムダオブジェクト が再生成されず、上位のLazyColumnが再コンポジションしても子要素の計算コストが抑えられます。LazyColumnではkey = { it.id }を必ず設定し、リスト項目の再利用(re‑composition)を最適化します。
5‑3. ビルド・配布フロー
5‑3‑1. リリースビルド作成
|
1 2 3 4 5 6 |
# AAB(推奨) ./gradlew bundleRelease # APK が必要な場合 ./gradlew assembleRelease |
bundleReleaseは Google Play の Android App Bundle 形式で、端末ごとに最適化された APK を自動生成します。
5‑3‑2. 署名設定(安全な管理)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
android { signingConfigs { release { // 環境変数から取得し、CI に平文を書かないよう徹底 storeFile file(System.getenv("KEYSTORE_PATH")) storePassword System.getenv("KEYSTORE_PASSWORD") keyAlias System.getenv("KEY_ALIAS") keyPassword System.getenv("KEY_PASSWORD") } } buildTypes { release { signingConfig signingConfigs.release minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } |
5‑3‑3. Google Play Console へのアップロード手順
- AAB を生成 →
app-release.aabがapp/build/outputs/bundle/release/に作成されます。 - Play Console にログインし、左メニューの 「リリース」→「アプリのリリース」 へ移動。
- 「内部テスト」トラックを新規作成し、AAB をドラッグ&ドロップでアップロード。
- テスター招待リンクを取得し、社内・外部テスターに配布。テストが完了したら同じ AAB を クローズドテスト → 本番リリース に昇格させます。
ポイント:内部テストは最短 2 時間で審査が通るため、リリース前の最終確認に有効です。
5‑4. ブランドガイドライン(公式ロゴ・表記)
| 項目 | 推奨内容 |
|---|---|
| Android Studio ロゴ | Android Developers のブランド資産ページから SVG を取得し、色は #3DDC84(Google グリーン)を使用。ロゴの比率・余白は公式ドキュメントに従うこと。 |
| Jetpack Compose ロゴ | Compose のロゴは「Material Design Icons」の compose アイコンを利用し、背景は透明、サイズは 48dp × 48dp が基本。改変や加工は禁止です。 |
| 表記統一 | 「Android Studio Flamingo」「Jetpack Compose」 は正式名称で使用し、略称(例: “Flam”)は避ける。 |
| カラーパレット | アプリ全体のテーマは Material3 の colorScheme をベースにし、ブランドカラーが必要な場合は primary に設定。ただし Android ロゴ色との直接的な組み合わせは視認性を確認すること。 |
注意:ロゴや名称の使用は Google の利用規約に準拠してください。商用・販促資料で使用する際は必ず最新のガイドラインを参照し、許諾が必要なケースでは公式窓口へ問い合わせましょう。
📚 まとめ(全体の要点)
- 開発環境 – Android Studio Flamingo (2023.3.1) 以上 + JDK 17 + 最新 Kotlin/AGP が必須。
- プロジェクト作成 –
buildFeatures.compose = trueと Compose BOM による依存関係一元管理でバージョン衝突を防止。 - Composable と State –
remember*系 API で UI の状態保持、アクセシビリティ属性は必ず付与。Material 3 テーマでブランド統一感を演出。 - 画面遷移 – Navigation Compose を利用し、パラメータは型安全に管理。サンプル Todo アプリは
rememberSaveable・LazyColumn・ViewModel への拡張がベストプラクティス。 - デバッグ/最適化 – Preview と Live Edit、
rememberによる再コンポジション削減、key指定で Lazy コンポーネントを高速化。 - ビルド・配布 – AAB 生成 → Play Console のテストトラック経由で安全にリリース。署名情報は環境変数で管理し、平文保存は絶対に行わない。
- ブランド遵守 – Android Studio と Jetpack Compose の公式ロゴ・表記は Google のブランドガイドラインに従い、カラーや比率を正しく使用すること。
これらの手順とベストプラクティスを踏まえて開発すれば、2024 年時点でも 安定かつ保守性の高い Jetpack Compose アプリ を迅速に構築できます。 Happy Compose!