コンポーザブルのプレビューで UI をプレビューする

コンポーザブルは、@Composable アノテーションが付いた関数で定義されます。

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

「Hello World」という語句を含む単純なテキスト要素

このコンポーザブルのプレビューを有効にするには、@Composable@Preview のアノテーションが付いた別のコンポーザブルを作成します。この新しいアノテーション付きコンポーザブルには、最初に作成したコンポーザブル SimpleComposable が含まれています。

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

@Preview アノテーションは、コンポーザブルをこのファイルのデザインビュー内で表示するように Android Studio に伝えます。編集を加えると、コンポーザブル プレビューがリアルタイムで更新されます。

Compose プレビューでのリアルタイムの更新を示す GIF

手動でコードにパラメータを追加して、Android Studio が @Preview をどのようにレンダリングするかをカスタマイズできます。@Preview アノテーションを同じ関数に複数回追加して、異なるプロパティのコンポーザブルをプレビューすることもできます。

@Preview コンポーザブルを使用する主なメリットの一つは、Android Studio のエミュレータに依存しなくて済むことです。エミュレータのメモリ使用量の多い起動を省略して、最終的なルックアンドフィールの変更を行うことができます。また、@Preview を使用すると、小さなコード変更を簡単に行い、テストできます。

@Preview アノテーションを最大限に活用するには、入力として受け取る状態と出力するイベントに基づいて画面を定義してください。

@Preview を定義

Android Studio には、コンポーザブルのプレビューを拡張する機能がいくつか用意されています。コンテナ デザインの変更やプレビューの操作ができるほか、プレビューをエミュレータまたはデバイスに直接デプロイすることも可能です。

サイズ

デフォルトでは、@Preview のサイズはコンテンツをラップできるように自動的に選択されます。サイズを手動で設定するには、heightDp パラメータと widthDp パラメータを追加します。これらの値はすでに dp として解釈されているため、.dp を追加する必要はありません。

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

「Hello World」と書かれた黄色の正方形

ダイナミック カラーのプレビュー

アプリでダイナミック カラーを有効にしている場合は、wallpaper 属性を使用して壁紙を切り替え、異なるユーザーが選択した壁紙に UI がどのように反応するかを確認します。Wallpaper クラスで提供されているさまざまな壁紙テーマから選択します。この機能を使用するには、Compose 1.4.0 以降が必要です。

さまざまなデバイスで使用

Android Studio Flamingo では、Preview アノテーションの device パラメータを編集して、さまざまなデバイスでのコンポーザブルの構成を定義できます。

コンポーズ可能な関数のサンプル

デバイス パラメータに空の文字列(@Preview(device = ""))が含まれている場合は、Ctrl+Space を押して自動入力を呼び出すことができます。次に、各パラメータの値を設定します。

サンプル関数の編集

自動入力から、リスト内の任意のデバイス オプション(@Preview(device = "id:pixel_4") など)を選択できます。または、spec:width=px,height=px,dpi=int… を選択して各パラメータの個別の値を設定し、カスタム デバイスを入力することもできます。

仕様リスト

適用するには Enter を押します。キャンセルするには Esc を押します。

無効な値を設定すると、宣言が赤色で下線付きになり、修正が利用可能になる場合があります(Alt + Enter(macOS の場合は ⌥ + ⏎)> [Replace with …])。検査では、入力内容に最も近い修正が提案されます。

無効な値の例

言語 / 地域

さまざまなユーザー ロケールをテストするには、locale パラメータを追加します。

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

「Bonjour」という単語とフランス国旗を含むシンプルなテキスト要素

背景色の設定

デフォルトでは、コンポーザブルは透明の背景で表示されます。背景を追加するには、showBackground パラメータと backgroundColor パラメータを追加します。backgroundColorColor 値ではなく ARGB の Long であることに留意してください。

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

「Hello World」と書かれた緑色の長方形

システム UI

プレビュー内にステータスバーとアクションバーを表示する必要がある場合は、次のように showSystemUi パラメータを追加します。

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

アクティビティとともにステータスバーとアクションバーが表示されたプレビュー ウィンドウ。

UI モード

uiMode パラメータには Configuration.UI_* 定数のいずれも指定可能で、それに応じてプレビューの動作を変更できます。たとえば、プレビューを夜間モードに設定して、テーマがどのように反応するかを確認できます。

Compose プレビューの UI

LocalInspectionMode

LocalInspectionMode CompositionLocal から読み取ることで、コンポーザブルがプレビューでレンダリングされているかどうか(検査可能なコンポーネント内)を確認できます。コンポジションがプレビューでレンダリングされている場合、LocalInspectionMode.currenttrue と評価されます。この情報を使用してプレビューをカスタマイズできます。たとえば、実際のデータを表示する代わりに、プレビュー ウィンドウにプレースホルダ画像を表示できます。

これにより、制限事項を回避することもできます。たとえば、ネットワーク リクエストを呼び出す代わりにサンプルデータを表示します。

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

@Preview を操作する

Android Studio には、定義したプレビューを操作できる機能が用意されています。この操作により、プレビューのランタイム動作を把握し、プレビューを使用して UI をより適切に操作できます。

インタラクティブ モード

インタラクティブ モードでは、プログラムを実行しているデバイス(スマートフォンやタブレットなど)で行う場合と同じようにプレビューを操作できます。インタラクティブ モードは、サンドボックス環境で(他のプレビューから分離された状態で)実行されます。プレビューの要素をクリックしたり、ユーザー入力を行ったりできます。このモードを使用することで、コンポーザブルのさまざまな状態、操作、アニメーションを簡単にテストできます。

プレビューの「インタラクティブ」ボタンをクリックするユーザー

プレビューを操作しているユーザーの動画

コード ナビゲーションとコンポーザブルの枠線

プレビューにカーソルを合わせると、中に含まれるコンポーザブルの枠線が表示されます。コンポーザブルの枠線をクリックすると、エディタビューがトリガーされ、そこからコンポーザブルの定義に移動できます。

ユーザーがプレビューにカーソルを合わせると、コンポーザブルの枠線が表示される

プレビューを実行

特定の @Preview は、エミュレータまたは物理デバイスで実行できます。プレビューは、新しい Activity と同じプロジェクト アプリ内にデプロイされるため、同じコンテキストと権限を共有します。権限がすでに付与されている場合は、権限をリクエストするボイラープレート コードを記述する必要はありません。

@Preview アノテーションの横またはプレビューの上部にあるプレビューを実行アイコン プレビューを実行アイコン をクリックすると、その @Preview が Android Studio によって接続済みデバイスまたはエミュレータにデプロイされます。

プレビューの [プレビューを実行] ボタンをクリックするユーザー

デバイスにプレビューをデプロイするユーザーの動画

@Preview のレンダリングをコピーする

レンダリングされたプレビューはすべて、右クリックして画像としてコピーできます。

プレビューをクリックして、画像としてコピーするユーザー

同じ @Preview アノテーションの複数のプレビュー

同じ @Preview コンポーザブルの複数のバージョンを、異なる仕様で、またはコンポーザブルに渡される異なるパラメータで表示できます。これにより、通常は記述する必要のあるボイラープレート コードを減らすことができます。

マルチプレビュー テンプレート

androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01 以降では、マルチプレビュー API テンプレート(@PreviewScreenSizes@PreviewFontScales@PreviewLightDark@PreviewDynamicColors)を使用して、1 つのアノテーションで一般的なシナリオで Compose UI をプレビューできます。

テンプレートを使用してさまざまなフォントと画面サイズをプレビューする

カスタムのマルチプレビュー アノテーションを作成する

マルチプレビューでは、それ自体に構成の異なる複数の @Preview アノテーションを含むアノテーション クラスを定義できます。このアノテーションをコンポーズ可能な関数に追加すると、さまざまなプレビューがすべて一度に自動的にレンダリングされます。たとえば、このアノテーションを使用して、コンポーザブルごとに定義を繰り返すことなく、複数のデバイス、フォントサイズ、テーマを同時にプレビューできます。

まず、独自のカスタム アノテーション クラスを作成します。

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

プレビュー コンポーザブルには次のカスタム アノテーションを使用できます。

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

小さいフォントと大きいフォントでコンポーザブルが表示されている Android Studio のデザインタブ

複数のマルチプレビュー アノテーションと通常のプレビュー アノテーションを組み合わせることで、より完全なプレビュー セットを作成できます。マルチプレビュー アノテーションを組み合わせたからといって、異なる組み合わせがすべて表示されるわけではありません。各マルチプレビュー アノテーションは個別に動作し、独自のバリアントのみをレンダリングします。

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

コンポーザブルがすべての構成で表示されている Android Studio のデザインタブ

マルチプレビューと通常のプレビューを組み合わせることで、大規模なプロジェクトの多くのプロパティをより包括的にテストできます。

@Preview と大規模なデータセット

多くの場合、大規模なデータセットをコンポーザブル プレビューに渡す必要があります。これを行うには、@PreviewParameter アノテーション付きのパラメータを追加して、サンプルデータをコンポーザブルのプレビュー関数に渡します。

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

サンプルデータを提供するには、PreviewParameterProvider を実装し、サンプルデータをシーケンスとして返すクラスを作成します。

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

これにより、シーケンス内のデータ要素ごとに 1 つのプレビューがレンダリングされます。

エリーゼ、フランク、ジュリアのコンポーザブルを示すプレビュー

複数のプレビューに同じプロバイダ クラスを使用できます。必要に応じ limit パラメータを設定して、プレビューの数を制限します。

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

制限事項とベスト プラクティス

Android Studio は、プレビュー コードをプレビュー領域で直接実行します。Android フレームワークのポートされた部分(Layoutlib)を利用するため、エミュレータや物理デバイスを実行する必要はありません。Layoutlib は、Android デバイスの外部で実行するように設計された Android フレームワークのカスタム バージョンです。このライブラリの目的は、デバイスでのレンダリングに非常に近いレイアウトのプレビューを Android Studio で提供することである。

プレビューの制限事項

Android Studio 内でプレビューがレンダリングされる仕組みにより、プレビューは軽量で、レンダリングに Android フレームワーク全体を必要としません。ただし、次のような制限があります。

  • ネットワークにアクセスできない
  • ファイルにアクセスできない
  • 一部の Context API を使用できない可能性がある

プレビューと ViewModels

コンポーザブル内で ViewModel を使用する場合、プレビューは制限されます。プレビュー システムでは、ViewModel に渡されるすべてのパラメータ(リポジトリ、ユースケース、マネージャーなど)を作成できません。また、ViewModel が依存関係注入に参加している場合(Hilt など)、プレビュー システムは依存関係グラフ全体をビルドして ViewModel を構築できません。

ViewModel でコンポーザブルをプレビューしようとすると、特定のコンポーザブルのレンダリング時に Android Studio にエラーが表示されます。

「ViewModel」のインスタンス化に失敗しましたというメッセージが表示された Android Studio の問題ペイン

ViewModel を使用するコンポーザブルをプレビューする場合は、ViewModel のパラメータをコンポーザブルの引数として渡して、別のコンポーザブルを作成する必要があります。これにより、ViewModel を使用するコンポーザブルをプレビューする必要がなくなります。

@Composable
fun AuthorColumn(viewModel: AuthorViewModel = viewModel()) {
  AuthorColumn(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorColumn(...) {
    name = NameLabel(name),
    posts = PostsList(posts)
  }
}

アノテーション クラス @Preview

Android Studio で @Preview アノテーションを Ctrl または ⌘ キーを押しながらクリックすると、プレビューのカスタマイズ時に調整できるパラメータのリストが表示されます。

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT,
    @Wallpaper val wallpaper: Int = Wallpapers.NONE,
)

参考情報

Android Studio が @Preview の使いやすさを促進する方法と、ツールに関するその他のヒントについては、ブログ「Compose ツール」をご覧ください。