技術本部Mobile Application Groupの荒です。AndroidアプリエンジニアとしてEightのAndroidアプリ開発に携わっています。
Eight AndroidではUI実装にJetpack Composeを使用しています。
その中で、共通で適用したいPreviewをまとめてカスタムマルチプレビューアノテーションとして定義し、プロジェクト内で定義されるComposableは基本的にこのPreviewで表示を確認するよう運用しています。
今回はそのEightで使用しているプレビューの内容を紹介するとともに、カスタムマルチプレビューアノテーションを使用することとした背景なども併せてご紹介します。
カスタムマルチプレビューアノテーションとは
まずはカスタムマルチプレビューアノテーション自体について軽く説明します。
マルチプレビューでは、複数のPreviewを指定したannotation classを定義することによって、そのアノテーションを使用することで指定した複数のPreviewを一度に表示できます。
次に簡単なサンプルを示します。
@Preview(showBackground = true, backgroundColor = Color.BLUE.toLong()) @Preview(showBackground = true, backgroundColor = Color.GREEN.toLong()) annotation class MyPreview @MyPreview @Composable fun Sample() { Text( modifier = Modifier.padding(16.dp), text = "Sample", color = androidx.compose.ui.graphics.Color.White ) }
例えば上記のようなMyPreviewを定義すると、ComposableにはMyPreviewを1つ指定するだけで次のように2つのPreviewを表示できます。

Android Developersではこちらに記載があるので、詳細を知りたい場合はぜひご覧ください。
導入の背景
Composableの導入初期に、レビュー時にComposableのKotlinコードから実際に正しい表示がされるのか判断しづらく感じる問題がEight Androidではありました。
その際に、標準的なパターンはマルチプレビューとして定義して、基本的にはそれを使用することでComposable関数の確認や考慮の負荷を下げられると考え、定義されました。
マルチプレビューを使う目的は標準的なパターンの確認であり、すべての表示崩れをこれで防ごうというものではないです。
Eight Androidで使われているアノテーション
それでは、Eight Android内で使用しているプレビューの設定をご紹介します。
/** * 通常確認されるべきプレビュー。 * 確認されるプレビューは以下。 * * - 英語、フォントサイズ通常 * - 日本語、フォントサイズ通常 * - 日本語、Android13以前での最大フォントサイズ(130%)かつサポートする最小端 * - 日本語、フォントサイズ小(85%) */ @Preview(locale = "en-US") @Preview(locale = "ja") @Preview(device = "spec:width=720px,height=1280px,dpi=300", locale = "ja", fontScale = 1.3f) @Preview(locale = "ja", fontScale = 0.85f) annotation class DefaultPreviews
多くの基本的なケースの表示を確認したり、一部のケースでの表示崩れを検知したりできるよう、次の4通りを定義しています。
① 英語での表示 ② 日本語での最も標準的な表示 ③ 最もUIが窮屈になる表示 ④ UIにゆとりがある表示
アノテーションの内容について
それでは上で紹介したアノテーションの内容について説明します。
まず上で①、②とした英語と日本語での標準的な表示は、主にロケールごとの文字列リソースを使った表示が確認できます。
次に③の「最もUIが窮屈になる表示」です。これは、例えば横長のComposableが、画面サイズが小さく、かつフォントサイズの設定も大きくしているユーザーの環境で表示崩れを起こしていないか確認できます。
この設定では、deviceとfontScaleを指定しています。
deviceで設定している解像度についてです。Eight Androidでは元々小さい端末で表示崩れがないことをQAで確認しており、その確認で使われている端末を動作を保証する最小の端末として、その縦横比、解像度を指定しています。
fontScaleは倍率が公式から明言されているわけではありませんが、Android13まででフォントサイズの設定を「最大」にした時の倍率の目安として1.3を指定しています。
表示崩れを防ぐという観点で見ると、表示言語との組み合わせやPreviewでは検証できない端末の表示サイズ設定など、確認の余地が多く残っているように見受けられると思います。しかし、背景で述べた通りすべての表示崩れを防ぐことが目的ではないため今の実装が採用されています。
最後に④の「UIにゆとりがある表示」です。これは③の反対で、フォントサイズの設定を「小」にした時の倍率の目安としてfontScaleに0.85を指定しています。
この④のPreviewでのみ表示崩れが起きることなどはあまりないですが、あまりにも空白が目立ち違和感のあるUIになっていないかなどの確認ができます。
Eight Android上では上記の4つをまとめたこのプレビューアノテーションを標準のPreviewとして運用しています。
余談
Eightで定義しているDefaultPreviewsとは別に、androidx.compose.ui:ui-tooling-previewへの依存があればSDKがいくつかのマルチプレビューアノテーションを用意してくれています。
特定のユースケースごとにプレビューがまとまっているので、ぜひ有効活用してみてください。
このブログ執筆時点では次のものが用意されています。
PreviewScreenSizes- スマホ、フォルダブル、タブレットなどの種類別のプレビュー
PreviewFontScale- フォント倍率0.85~2倍のプレビュー
PreviewLightDark- ライトテーマとダークテーマのプレビュー
PreviewDynamicColors- さまざまな壁紙色のプレビュー(ダイナミックカラーの確認用と思われます)
おわりに
Eightの開発で使用しているマルチプレビューについて紹介しました。
マルチプレビューをアプリの要件に沿わせることで、それぞれのコンポーネントが要件を充足していることを確認することが容易になります。
また、Eightではこのマルチプレビューを定義するにあたってアプリがサポートするべき文字サイズ、端末サイズの要件の明確化もできました。