さまざまな画面サイズに合わせて開発する


アプリは、あらゆるサイズの Wear OS デバイスで適切に動作し、利用可能な追加スペースを活用し、小さな画面でも適切に表示される必要があります。このガイドでは、このようなユーザー エクスペリエンスを実現するための推奨事項について説明します。

アダプティブ レイアウトの設計原則について詳しくは、設計ガイダンスをご覧ください。

マテリアル 3 を使用してレスポンシブ レイアウトを作成する

レイアウトには割合ベースのマージンを使用する必要があります。Wear Compose Material 3 では、ScreenScaffold がパーセンテージベースのパディングを自動的に計算し、contentPadding をコンテンツ ラムダに提供します。この contentPadding パラメータを TransformingLazyColumn に渡します。

次のコード スニペットでは、TransformingLazyColumn コンポーネントを使用して、さまざまな Wear OS 画面サイズで見栄えのするコンテンツを作成しています。

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

この例では、ScreenScaffold と AppScaffold も示しています。これらは、アプリと個々の画面(ナビゲーション ルート)の間で調整を行い、正しいスクロール動作と TimeText の配置を確保します。

上下のパディングについては、次の点にも注意してください。

  • Modifier.minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding や ButtonDefaults.minimumVerticalListContentPadding など)を使用することで、TransformingLazyColumn は、それらのアイテムがリストの端に表示されるときに、少なくとも推奨される上下のパディングを使用します。
  • リストの最初のアイテムに、通常の Text コンポーザブルではなく ListHeader を使用している。

詳細な仕様については、Figma デザインキットをご覧ください。詳細と例については、以下をご覧ください。

  • Horologist ライブラリ - Wear OS 向けに最適化された差別化されたアプリを構築するためのヘルパーを提供します。
  • ComposeStarter サンプル - このガイドで説明されている原則を示すサンプル。
  • JetCaster サンプル - Horologist ライブラリを使用して、さまざまな画面サイズに対応するアプリを構築する、より複雑な例。

アプリでスクロール レイアウトを使用する

画面を実装する際のデフォルトの選択肢として、このページで前述したスクロール レイアウトを使用します。これにより、ユーザーはディスプレイの設定や Wear OS デバイスの画面サイズに関係なく、アプリのコンポーネントにアクセスできます。

さまざまなデバイスサイズとフォント スケーリングの影響

さまざまなデバイスサイズとフォント スケーリングの影響。

ダイアログ

また、ダイアログはスクロール可能にする必要があります。ただし、スクロール可能にしない正当な理由がある場合は除きます。 AlertDialog コンポーネントはレスポンシブで、コンテンツがビューポートの高さを超える場合はデフォルトでスクロール可能です。

カスタム画面では、スクロールしないレイアウトが必要になる場合があります。

一部の画面は、スクロールしないレイアウトに適している場合があります。たとえば、メディアアプリのメイン プレーヤー画面や、フィットネス アプリのワークアウト画面などです。

このような場合は、Figma デザインキットに記載されている正規のガイダンスを参照し、適切なマージンを使用して、画面サイズに対応するデザインを実装してください。

ブレークポイントを使用して差別化されたエクスペリエンスを提供する

ディスプレイが大きくなると、追加のコンテンツや機能を導入できます。このような差別化されたエクスペリエンスを実装するには、画面サイズのブレークポイントを使用して、画面サイズが 225 dp を超えたときに異なるレイアウトを表示します。

const val LARGE_DISPLAY_BREAKPOINT = 225

@Composable
fun isLargeDisplay() =
    LocalConfiguration.current.screenWidthDp >= LARGE_DISPLAY_BREAKPOINT

// ...
// ... use in your Composables:
    if (isLargeDisplay()) {
        // Show additional content.
    } else {
        // Show content only for smaller displays.
    }
    // ...

デザイン ガイダンスでは、このような機会について詳しく説明しています。

プレビューを使用して画面サイズとフォントサイズの組み合わせをテストする

Compose プレビューは、さまざまな Wear OS 画面サイズ向けの開発に役立ちます。デバイスとフォント スケーリングのプレビュー定義を両方使用して、次の内容を確認します。

  • サイズが極端な場合(最小の画面に最大のフォントを組み合わせた場合など)の画面の表示。
  • ブレークポイント間で差別化されたエクスペリエンスがどのように動作するか。

アプリのすべての画面で WearPreviewDevices と WearPreviewFontScales を使用してプレビューを実装してください。Wear OS プレビュー、カスタム ハードウェア仕様、スクロール リストのプレビューの構成について詳しくは、Compose for Wear OS で UI をプレビューするをご覧ください。

@WearPreviewDevices
@WearPreviewFontScales
@Composable
fun ComposeListPreview() {
    ComposeList()
}

スクリーンショット テスト

スクリーンショット テストでは、プレビュー テストだけでなく、さまざまな既存のハードウェア サイズに対してテストを行うことができます。これは、それらのデバイスをすぐに利用できない場合や、他の画面サイズでは問題が発生しない場合に特に便利です。

スクリーンショット テストは、コードベースの特定の場所で回帰を特定するのにも役立ちます。

サンプルでは、スクリーンショット テストに Roborazzi を使用しています。

  1. Roborazzi を使用するようにプロジェクトとアプリの build.gradle ファイルを構成します。
  2. アプリの画面ごとにスクリーンショット テストを作成します。たとえば、次のコードは、リストを含む画面のスクリーンショット テストを示しています。
@RunWith(ParameterizedRobolectricTestRunner::class)
class ComposeListScreenTest(
    override val device: WearDevice
) : WearScreenshotTest() {
    override val tolerance = 0.02f

    @Test
    fun myScreenTest() =
        runTest {
            AppScaffold {
                ComposeList()
            }
        }

    companion object {
        @JvmStatic
        @ParameterizedRobolectricTestRunner.Parameters
        fun devices() = WearDevice.entries
    }
}

注意すべき重要な点:

  • WearDevice.entries には、最も一般的な Wear OS デバイスの定義が含まれているため、代表的な画面サイズでテストが実行されます。

ゴールデン イメージを生成する

画面の画像を生成するには、ターミナルで次のコマンドを実行します。

./gradlew recordRoborazziDebug

イメージを確認する

既存のイメージに対する変更を確認するには、ターミナルで次のコマンドを実行します。

./gradlew verifyRoborazziDebug

スクリーンショット テストの完全な例については、ComposeStarter のサンプルをご覧ください。