ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-03-29中級

Antigravity × Jetpack Compose で Android UI を AI アシスト開発する実践ガイド

Antigravity IDE と Jetpack Compose を組み合わせた Android UI 開発の実践手法を解説。AI によるコンポーネント生成、プレビュー活用、テーマ設計まで具体的なコード例とともに紹介します。

antigravity435jetpack-compose4android27kotlin6ui-developmentandroid-studio3

取り組みの背景 — なぜ Antigravity × Jetpack Compose なのか

Android アプリの UI 開発は、Jetpack Compose の登場によって宣言的なコード記述が標準になりましました。しかし、複雑なレイアウトの組み立てやテーマの一貫性維持、アニメーション実装など、UI 開発には依然として多くの手作業が伴います。

ここで Antigravity IDE の AI エージェント機能を組み合わせると、Composable 関数の雛形生成からプレビュー用データの作成、Material Design 3 テーマの自動構成まで、UI 開発のあらゆる工程を効率化できます。ここではAntigravity と Jetpack Compose を組み合わせた実践的なワークフローを、具体的なコード例とともに解説します。

対象読者は、Kotlin と Jetpack Compose の基本を理解しており、AI IDE を活用して開発効率を上げたい方です。

Antigravity で Android プロジェクトをセットアップする

Antigravity で Jetpack Compose プロジェクトを扱うには、まず適切なプロジェクト構成を AI に認識させる点が肝心です。プロジェクトのルートディレクトリを開いた状態で、AGENTS.md ファイルにプロジェクトの技術スタックを記述しておくと、エージェントが生成するコードの精度が大幅に向上します。

// AGENTS.md に記載する技術スタック情報の例
// (Markdownファイルとして記述)
 
// ## Tech Stack
// - Language: Kotlin 2.1
// - UI Framework: Jetpack Compose (BOM 2026.03.00)
// - Architecture: MVVM + Clean Architecture
// - DI: Hilt
// - Navigation: Compose Navigation
// - Theme: Material Design 3 (Dynamic Color対応)

この情報をもとに、Antigravity のエージェントは Compose のベストプラクティスに沿ったコードを生成してくれます。たとえば「ユーザープロフィール画面を作って」と指示するだけで、Material 3 のコンポーネントを使った Composable 関数が MVVM パターンに従って生成されます。

AI でコンポーザブル関数を効率的に生成する

Antigravity のインラインチャット(Cmd+I / Ctrl+I)を使うと、Composable 関数を自然言語から直接生成できます。ポイントは、具体的な UI 要件を伝えることです。

// Antigravity に以下のようなプロンプトを送る:
// 「商品一覧画面のカードコンポーネントを作成して。
//  画像・商品名・価格・お気に入りボタンを含む。
//  Material 3のCardコンポーネントを使用。」
 
// 生成されるコード例:
@Composable
fun ProductCard(
    product: Product,
    onFavoriteClick: (String) -> Unit,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 8.dp),
        shape = RoundedCornerShape(12.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
    ) {
        Column {
            // 商品画像
            AsyncImage(
                model = product.imageUrl,
                contentDescription = product.name,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(200.dp),
                contentScale = ContentScale.Crop
            )
 
            Column(modifier = Modifier.padding(16.dp)) {
                // 商品名
                Text(
                    text = product.name,
                    style = MaterialTheme.typography.titleMedium,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis
                )
 
                Spacer(modifier = Modifier.height(4.dp))
 
                // 価格とお気に入りボタン
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(
                        text = "¥${product.price}",
                        style = MaterialTheme.typography.titleLarge,
                        color = MaterialTheme.colorScheme.primary
                    )
                    IconButton(onClick = { onFavoriteClick(product.id) }) {
                        Icon(
                            imageVector = if (product.isFavorite)
                                Icons.Filled.Favorite else Icons.Outlined.FavoriteBorder,
                            contentDescription = "お気に入り",
                            tint = if (product.isFavorite)
                                MaterialTheme.colorScheme.error
                            else MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                }
            }
        }
    }
}
 
// 期待される出力: Material 3 のカードUIに商品情報が表示され、
// お気に入りボタンのトグルが動作する

生成されたコードは、@Preview アノテーションを追加して Android Studio のプレビュー機能ですぐに確認できます。Antigravity に「プレビュー用の関数も追加して」と指示すれば、サンプルデータ付きのプレビュー関数も自動生成されます。

Material Design 3 テーマを AI で構成する

アプリ全体のテーマ設計は、一貫性のある UI を実現するために欠かせません。Antigravity を使えば、ブランドカラーから Material 3 のカラースキームを自動生成できます。

// プロンプト例:
// 「ブランドカラー #6750A4 をベースに
//  Material 3 のダイナミックカラー対応テーマを作成して」
 
// 生成されるテーマ設定:
private val LightColorScheme = lightColorScheme(
    primary = Color(0xFF6750A4),
    onPrimary = Color(0xFFFFFFFF),
    primaryContainer = Color(0xFFEADDFF),
    onPrimaryContainer = Color(0xFF21005D),
    secondary = Color(0xFF625B71),
    onSecondary = Color(0xFFFFFFFF),
    secondaryContainer = Color(0xFFE8DEF8),
    onSecondaryContainer = Color(0xFF1D192B),
    tertiary = Color(0xFF7D5260),
    surface = Color(0xFFFFFBFE),
    onSurface = Color(0xFF1C1B1F),
    background = Color(0xFFFFFBFE),
    error = Color(0xFFB3261E)
)
 
private val DarkColorScheme = darkColorScheme(
    primary = Color(0xFFD0BCFF),
    onPrimary = Color(0xFF381E72),
    primaryContainer = Color(0xFF4F378B),
    onPrimaryContainer = Color(0xFFEADDFF),
    secondary = Color(0xFFCCC2DC),
    onSecondary = Color(0xFF332D41),
    surface = Color(0xFF1C1B1F),
    onSurface = Color(0xFFE6E1E5),
    background = Color(0xFF1C1B1F),
    error = Color(0xFFF2B8B5)
)
 
@Composable
fun AppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = when {
        // Android 12以降でダイナミックカラーをサポート
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context)
            else dynamicLightColorScheme(context)
        }
        darkTheme -> DarkColorScheme
        else -> LightColorScheme
    }
 
    MaterialTheme(
        colorScheme = colorScheme,
        typography = AppTypography,
        content = content
    )
}
 
// 期待される出力: ライト/ダークテーマが自動切り替えされ、
// Android 12以降ではダイナミックカラーが適用される

テーマのカスタマイズでは、Typography の定義も重要です。「日本語フォントに Noto Sans JP を使った Typography 設定を追加して」と指示すると、ウェイトごとのフォント定義まで含めたコードが生成されます。

LazyColumn / LazyGrid でパフォーマンスを意識したリスト UI を構築する

大量のデータを表示するリスト画面は、パフォーマンスへの配慮が不可欠です。Antigravity のエージェントにパフォーマンス要件を伝えることで、最適化済みのリストコンポーネントを生成できます。

// プロンプト例:
// 「商品一覧を2列グリッドで表示する画面を作成。
//  ページング対応、プルリフレッシュ付き。」
 
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ProductListScreen(
    viewModel: ProductListViewModel = hiltViewModel()
) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()
    val pullRefreshState = rememberPullToRefreshState()
 
    PullToRefreshBox(
        isRefreshing = uiState.isRefreshing,
        onRefresh = { viewModel.refresh() },
        state = pullRefreshState
    ) {
        LazyVerticalGrid(
            columns = GridCells.Fixed(2),
            contentPadding = PaddingValues(8.dp),
            horizontalArrangement = Arrangement.spacedBy(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(
                items = uiState.products,
                key = { it.id } // リコンポジション最適化
            ) { product ->
                ProductCard(
                    product = product,
                    onFavoriteClick = { viewModel.toggleFavorite(it) }
                )
            }
 
            // ページング: 末尾にローディングインジケーター
            if (uiState.hasMore) {
                item(span = { GridItemSpan(2) }) {
                    LaunchedEffect(Unit) {
                        viewModel.loadMore()
                    }
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(16.dp),
                        contentAlignment = Alignment.Center
                    ) {
                        CircularProgressIndicator()
                    }
                }
            }
        }
    }
}
 
// 期待される出力: 2列グリッドに商品カードが並び、
// スクロール末尾で自動ページング、上部スワイプでリフレッシュ

key パラメータの指定は、リコンポジション時のパフォーマンスに大きく影響します。Antigravity にこの点を明示的に伝えることで、最初からパフォーマンスを意識したコードが生成されます。

さらに詳しいパフォーマンス最適化のテクニックについては、Antigravity AI デバッグ&パフォーマンス最適化 プロフェッショナルガイド で体系的に解説しています。

Compose Navigation と画面遷移アニメーション

複数画面を持つアプリでは、ナビゲーション設計が重要になります。Antigravity を使って、型安全なナビゲーショングラフとカスタム遷移アニメーションを構築しましょう。

// 型安全なルート定義
@Serializable
sealed class Route {
    @Serializable
    data object ProductList : Route()
 
    @Serializable
    data class ProductDetail(val productId: String) : Route()
 
    @Serializable
    data object Cart : Route()
}
 
// ナビゲーションホスト
@Composable
fun AppNavigation(navController: NavHostController = rememberNavController()) {
    NavHost(
        navController = navController,
        startDestination = Route.ProductList,
        enterTransition = {
            slideIntoContainer(
                towards = AnimatedContentTransitionScope.SlideDirection.Left,
                animationSpec = tween(300)
            )
        },
        exitTransition = {
            slideOutOfContainer(
                towards = AnimatedContentTransitionScope.SlideDirection.Left,
                animationSpec = tween(300)
            )
        },
        popEnterTransition = {
            slideIntoContainer(
                towards = AnimatedContentTransitionScope.SlideDirection.Right,
                animationSpec = tween(300)
            )
        },
        popExitTransition = {
            slideOutOfContainer(
                towards = AnimatedContentTransitionScope.SlideDirection.Right,
                animationSpec = tween(300)
            )
        }
    ) {
        composable<Route.ProductList> {
            ProductListScreen(
                onProductClick = { productId ->
                    navController.navigate(Route.ProductDetail(productId))
                }
            )
        }
        composable<Route.ProductDetail> { backStackEntry ->
            val route = backStackEntry.toRoute<Route.ProductDetail>()
            ProductDetailScreen(
                productId = route.productId,
                onBackClick = { navController.popBackStack() },
                onCartClick = { navController.navigate(Route.Cart) }
            )
        }
        composable<Route.Cart> {
            CartScreen(onBackClick = { navController.popBackStack() })
        }
    }
}
 
// 期待される出力: 画面間をスライドアニメーション付きで遷移し、
// 戻る操作では逆方向のアニメーションが再生される

Antigravity のエージェントに「画面遷移のアニメーションもカスタマイズして」と追加指示を送ると、フェードやスケールなど多様なトランジションパターンを提案してくれます。

まとめ

Antigravity IDE と Jetpack Compose を組み合わせることで、Android UI 開発の生産性を大幅に向上させることができます。本記事で紹介したポイントをまとめると、AGENTS.md によるプロジェクト情報の共有、インラインチャットを使った Composable 関数の生成、Material 3 テーマの自動構成、パフォーマンスを意識したリスト実装、そして型安全なナビゲーション設計です。

AI が生成したコードをそのまま使うのではなく、プレビュー機能やテストで検証しながら改善を重ねることで、品質と開発速度を両立できます。Antigravity のエージェント機能をさらに活用したい方には、AGENTS.md によるマルチエージェント設計 も合わせてご覧ください。

シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

アプリ開発2026-07-18
「Compose ファースト」の後で、View の画面をどの順に移すか — 画面数ではなく変更頻度で決める
Google が Android 開発を Compose ファーストと表明しました。View ベースの画面をどの順で移すかを、画面数ではなく git の変更履歴から決める判断軸と、実際に動かしたスコアリングスクリプトをまとめます。
アプリ開発2026-06-27
AI Studio が選んだ Gradle と AGP のバージョンが、既存アプリのビルドを静かに壊す前に
AI Studio が生成した Kotlin/Compose 画面を既存の Android アプリへ取り込むと、AGP・Kotlin・依存ライブラリのバージョンがずれてビルドが静かに壊れます。version catalog で単一の真実を固定し、取り込み口で生成側の宣言を検査するゲートの設計を、実測とコードでまとめました。
アプリ開発2026-06-17
ダイアログが重なる前に止める — 課金・レビュー誘導・リワード広告を1か所のゲートで束ねる
ペイウォール・レビュー誘導・リワード広告が同じ瞬間に重なって出る不具合を、優先度つきの中央ゲートで根治した実装記録です。Antigravityのエージェントに散らばったshow()呼び出しの掃き出しを任せ、表示ポリシーは自分で握る線引きで進めました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →