➰
初めてのJetpack Compose導入──XMLからの段階的移行で得た知見
初めてのJetpack Compose導入──XMLからの段階的移行で得た知見
はじめに
本記事では、既存アプリの一部画面を XMLからJetpack Composeへ段階的に移行 した際の実体験をまとめます。
自分自身、この案件で初めてComposeを使用し、既存コードベースの中で徐々に導入を進める担当をしました。
「Composeに興味はあるけど、既存プロジェクトにどう組み込むべきか悩んでいる」
そんな方の参考になれば幸いです。
XMLとComposeの共存構成
既存の画面をすべてComposeに置き換えるのはリスクが高いため、まずは 部分導入 から始めました。
主に以下の2パターンを使い分けています。
1. XMLにComposeViewを埋め込むパターン
既存のXMLレイアウトの中に、部分的にComposeを差し込む方法です。
この方法なら既存のViewModelやDataBindingを活かしつつ導入できます。
<!-- layout_sample.xml -->
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
// Fragment内でComposeをセット
binding.composeContainer.setContent {
MyComposableScreen(viewModel)
}
2. Compose側から従来のViewを呼び出す
逆に、Compose画面内で既存のViewを呼び出したい場合はAndroidViewを使います。
AndroidView(
factory = { context -> LayoutInflater.from(context).inflate(R.layout.old_view, null) }
)
このように、ComposeView / AndroidViewを組み合わせることで、段階的な移行が可能 でした。
実際に直面した課題と解決策
| 課題 | 原因 | 解決策 |
|---|---|---|
| 状態管理の分離が難しい | ViewModelのLiveDataをそのまま扱うと非Compose的 |
collectAsState()を活用してState変換 |
| レイアウト崩れ | XMLとComposeでmargin/paddingの扱いが異なる | Composeテーマ側でdp値を統一管理 |
| Navigationの整合性 | Navigation ComponentとCompose Navigationの共存 | Compose部分をNavHost内に閉じ込める設計に変更 |
| Previewが動かない | 実データ依存でコンパイルエラー |
@PreviewParameterやFakeデータ導入で対応 |
移行時に意識したポイント
- 「1画面ずつ安全に」 を徹底。全リプレースはせず、リスクの低い部分から導入。
- UIルールをComposeテーマで統一。 XMLと色味・余白を揃えてデザイン崩壊を防止。
- ViewModelとの依存関係を最小化。 状態管理は単方向データフローを意識。
- 再利用を意識したComposable設計。 Slot APIやModifierを積極的に活用。
実装のコツ・運用Tips
-
Previewで小さく確認してから実機テスト。
Composeは試行錯誤のスピードが速いので、Previewをうまく使うと開発効率が上がる。 -
状態保持は
rememberSaveableを活用。
回転や再生成に強いUIを実現できる。 -
UIイベントは
LaunchedEffectで安全に処理。
初期化時・再表示時など、ライフサイクルを意識した実装が重要。 -
チーム共有ではPreviewのスクリーンショット活用。
デザイナー・QAとの確認がしやすい。
Compose導入後に感じたメリットと課題
メリット
- XMLに比べて画面構築スピードが向上
- UI修正や動的レイアウト対応が容易
- コード量の削減・可読性の向上
課題
- Previewが100%実機再現ではない
- チーム内での記法統一(命名・Modifier順など)が必要
- Compose Navigationの学習コスト
まとめ
初めてのCompose導入では、「一気に移行せず、共存しながら進める」 のが現実的でした。
実装段階で特に重要だと感じたのは、
- 状態管理の整理
- テーマ統一
- Preview活用
今後はNavigationやテスト周りもCompose化を進めつつ、よりモジュール化された設計を目指していきたいと思います。
Discussion