Wear OS 向け Compose の Codelab

1. はじめに

4d28d16f3f514083.png

Wear OS 向け Compose を使用することで、Jetpack Compose を使用したモバイルアプリの作成について身に付けた知識をウェアラブル デバイスに活用できます。

Material You の組み込みサポートを備える Wear OS 向け Compose は、モバイルと同様、UI 開発を簡素化して加速し、少ないコードで美しいアプリを作成するうえで有効です。

この Codelab では、Compose に関してある程度の知識をお持ちであることを前提としていますが、エキスパートであることは必要としません。

いくつかの Wear 固有のコンポーザブル(単純なものも複雑なものも)を作成し、最終的に Wear OS 向けの独自のアプリの作成を開始できます。それでは始めましょう。

学習内容

  • モバイルと Wear OS の Compose の類似点と相違点
  • モバイル上の一般的なコンポーザブルと類似した Wear OS コンポーザブル
  • 新しい Wear OS コンポーザブル
  • Wear OS の LazyColumnScalingLazyColumn)
  • Wear OS の Scaffold のバージョン

作成するアプリの概要

Wear OS 向けに最適化されたコンポーザブルのスクロール可能なリストを表示する簡単なアプリを作成します。

Scaffold を使用するため、上部に時刻を湾曲したテキストで表示し、周辺減光の処理を行い、最後にデバイスの側面に沿ったスクロール インジケーターも表示します。

Codelab を完了すると、アプリは次のようになります。

b7bd20036af4859d.gif

前提条件

2. 設定方法

このステップでは、環境を設定してスターター プロジェクトをダウンロードします。

必要なもの

  • Android Studio の最新の安定版
  • Wear OS デバイスまたはエミュレータ(初めて使用する場合はこちらで設定方法をご確認ください)

コードをダウンロードする

git がインストールされている場合は、以下のコマンドをそのまま実行してこのリポジトリからコードのクローンを作成できます。git がインストールされているかどうかを確認するには、ターミナルまたはコマンドラインで「git --version」と入力し、正しく実行されることを確認します。

git clone https://github.com/googlecodelabs/compose-for-wear-os.git
cd compose-for-wear-os

git がない場合は、次のボタンをクリックして、この Codelab のすべてのコードをダウンロードできます。

ZIP をダウンロード

どちらのモジュールも、Android Studio のツールバーで実行構成を変更することでいつでも実行できます。

8a2e49d6d6d2609d.png

Android Studio でプロジェクトを開く

  1. [Welcome to Android Studio] ウィンドウで、1f5145c42df4129a.png [Open an Existing Project] を選択します。
  2. [Download Location] フォルダを選択します。
  3. Android Studio にプロジェクトがインポートされたら、Wear OS エミュレータまたは物理デバイスで start モジュールと finished モジュールを実行できるかどうかをテストします。
  4. start モジュールは次のスクリーンショットのようになります。すべての作業をこのモジュールで行います。

7668d2915856b849.png

start コードを確認する

  • build.gradle: 基本的なアプリ構成が含まれています。コンポーザブル Wear OS アプリの作成に必要な依存関係が含まれています。モバイルと Wear OS の Jetpack Compose の類似点と相違点について説明します。
  • main > AndroidManifest.xml: Wear OS アプリの作成に必要な要素が含まれています。これは Compose 以外のアプリと同じで、モバイルアプリと類似しています。そのため、確認は行いません。
  • main > theme/ フォルダには、Compose がテーマで使用する Color ファイル、Type ファイル、Theme ファイルが含まれています。
  • main > MainActivity.kt には、Compose でアプリを作成するためのボイラープレートが含まれています。また、これにはアプリのトップレベル コンポーザブル(ScaffoldScalingLazyList など)も含まれます。
  • main > ReusableComponents.kt には、作成する Wear 固有のコンポーザブルのほとんどの関数が含まれています。このファイルで多くの作業を行います。

3.依存関係を確認する

Wear 関連の依存関係の変更のほとんどは、最上位のアーキテクチャ レイヤ(以下では赤でハイライト表示されています)に反映されます。

d92519e0b932f964.png

つまり、すでに Jetpack Compose で使用している依存関係の多くは、Wear OS をターゲットにしても変更されません。たとえば、UI、ランタイム、コンパイラ、アニメーションの依存関係に変更はありません。

ただし、今までにモバイルアプリで使用していたライブラリとは異なる適切な Wear OS の MaterialFoundationNavigation ライブラリを使用する必要があります。

違いを明確にするために、次の比較をご覧ください。

Wear OS の依存関係(androidx.wear.*)

比較

モバイルの依存関係(androidx.*)

androidx.wear.compose:compose-material

代用

androidx.compose.material:material

androidx.wear.compose:compose-navigation

代用

androidx.navigation:navigation-compose

androidx.wear.compose:compose-foundation

追加して

androidx.compose.foundation:foundation

1. デベロッパーは、Wear Compose Material ライブラリで拡張されたマテリアル リップルやマテリアル アイコンなど、その他のマテリアル関連のライブラリを引き続き使用できます。

build.gradle を開き、start モジュールで「TODO: Review Dependencies」を検索します(このステップは依存関係の確認のみを目的としています。コードは追加しません)。

start/build.gradle:

// TODO: Review Dependencies
// General Compose dependencies
implementation "androidx.activity:activity-compose:$activity_compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.foundation:foundation:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version"

// Compose for Wear OS Dependencies
implementation "androidx.wear.compose:compose-material:$wear_compose_version"

// Foundation is additive, so you can use the mobile version in your Wear OS app.
implementation "androidx.wear.compose:compose-foundation:$wear_compose_version"

一般的な Compose 依存関係の多くは把握しておく必要があるため、ここでは扱っていません。

Wear OS の依存関係について見ていきましょう。

前述のように、Wear OS 固有のバージョンの materialandroidx.wear.compose:compose-material)のみが含まれます。つまり、プロジェクトに androidx.compose.material:material が表示される、または含まれることはありません。

Wear のマテリアルでは他のマテリアル ライブラリを使用できることを再度想起することが重要です。この Codelab では、androidx.compose.material:material-icons-extended を追加してこれを行います。

最後に、Compose(androidx.wear.compose:compose-foundation)用の Wear foundation ライブラリを含めます。これは付加的なものであるため、モバイル側で使用する foundation で使用できます。実際、一般的な Compose 依存関係にすでに含まれていることにお気づきかもしれません。

依存関係を理解したところで、メインアプリを見てみましょう。

4. MainActivity を確認する

すべての作業は

start

モジュールで行うため、開くファイルはすべてこのモジュールに配置してください。

まず、start モジュールの MainActivity を開きます。

これは、ComponentActivity を拡張し、setContent { WearApp() } を使用して UI を作成する、非常にシンプルなクラスです。

Compose についてすでにご存じのとおり、これはおなじみのものです。UI の設定だけを行います。

コンポーズ可能な関数 WearApp() まで下にスクロールします。コード自体について説明する前に、コード全体に分散された多くの TODO に触れておきましょう。これらはそれぞれ、この Codelab のステップを表します。今回は無視して問題ありません。

次のようになります。

面白い WearApp() のコード:

WearAppTheme {
    // TODO: Swap to ScalingLazyListState
    val listState = rememberLazyListState()

    /* *************************** Part 4: Wear OS Scaffold *************************** */
    // TODO (Start): Create a Scaffold (Wear Version)

        // Modifiers used by our Wear composables.
        val contentModifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
        val iconModifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center)

        /* *************************** Part 3: ScalingLazyColumn *************************** */
        // TODO: Create a ScalingLazyColumn (Wear's version of LazyColumn)
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(
                top = 32.dp,
                start = 8.dp,
                end = 8.dp,
                bottom = 32.dp
            ),
            verticalArrangement = Arrangement.Center,
            state = listState
        ) {

            // TODO: Remove item; for beginning only.
            item { StartOnlyTextComposables() }

            /* ******************* Part 1: Similar composables to Mobile ******************* */
            item { ButtonExample(contentModifier, iconModifier) }
            item { TextExample(contentModifier) }
            item { CardExample(contentModifier, iconModifier) }

            /* ********************* Part 2: Wear OS Only composables ********************* */
            item { ChipExample(contentModifier, iconModifier) }
            item { ToggleChipExample(contentModifier) }
        }

    // TODO (End): Create a Scaffold (Wear Version)

}

まず、テーマ WearAppTheme { } を設定します。これは、モバイルで記述するのとまったく同じ方法、つまり、色、タイポグラフィ、シェイプを使用して MaterialTheme を設定する際と同じ方法です。

ただし、Wear OS の場合、通常は、円形と非円形のデバイス向けに最適化されたデフォルトのマテリアル ウェア シェイプを使用することをおすすめします。そのため、theme/Theme.kt では、シェイプはオーバーライドされていません。

必要に応じて theme/Theme.kt を開いて詳細を確認することもできますが、ここでもモバイルと同じです。

次に、これから作成する Wear コンポーザブル用の修飾子を作成します。そのため、毎回指定する必要はありません。ほとんどの場合、コンテンツの中央に配置され、パディングが追加されます。

次に、LazyColumn を作成します。これは、(モバイルの場合と同様に)縦方向にスクロールするアイテムのリストを生成するために使用されます。

コード:

item { StartOnlyTextComposables() }

/* ******************* Part 1: Similar composables to Mobile ******************* */
item { ButtonExample(contentModifier, iconModifier) }
item { TextExample(contentModifier) }
item { CardExample(contentModifier, iconModifier) }

/* ********************* Part 2: Wear OS Only composables ********************* */
item { ChipExample(contentModifier, iconModifier) }
item { ToggleChipExample(contentModifier) }

アイテム自体については、StartOnlyTextComposables() のみが UI を生成します(残りのコードは Codelab 全体を通して取り上げます)。

これらの関数は実際の ReusableComponents.kt ファイルに含まれています。次のセクションで説明します。

Wear OS 向け Compose を使ってみましょう。

5. シンプルなコンポーザブルを追加する

まずは、皆さんがすでに使い慣れていると思われる 3 つのコンポーザブル(ButtonTextCard)から始めます。

最初に、Hello World コンポーザブルを削除します。

TODO: Remove item」を検索して、コメントとその下の行の両方を消去します。

ステップ 1

// TODO: Remove item; for beginning only.
item { StartOnlyTextComposables() }

次に、最初のコンポーザブルを追加しましょう。

ボタン コンポーザブルを作成する

start モジュールの ReusableComponents.kt を開き、「TODO: Create a Button Composable」を検索して、現在のコンポーザブル メソッドを次のコードに置き換えます。

ステップ 2

// TODO: Create a Button Composable (with a Row to center)
@Composable
fun ButtonExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Row(
        modifier = modifier,
        horizontalArrangement = Arrangement.Center
    ) {
        // Button
        Button(
            modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
            onClick = { /* ... */ },
        ) {
            Icon(
                imageVector = Icons.Rounded.Phone,
                contentDescription = "triggers phone action",
                modifier = iconModifier
            )
        }
    }
}

(このコードが存在する)ButtonExample() コンポーズ可能な関数が、中央のボタンを生成するようになりました。

コードを詳しく見ていきましょう。

Row は、円形の画面上で Button コンポーザブルを中央に配置するためにのみ使用されます。これを行うには、MainActivity で作成した修飾子を適用し、この関数に渡します。後で円形の画面をスクロールしたときに、コンテンツが切り取られないようにします(そのため、コンテンツが中央に配置されます)。

次に、Button を作成します。このコードは、モバイルのボタンで使用するコードと同じですが、今回は ButtonDefault.LargeButtonSize を使用します。これらは Wear OS デバイス向けに最適化された現在のサイズであるため、必ず使用してください。

次に、クリック イベントを空のラムダに設定します。今回の場合、これらのコンポーザブルはデモのみを目的としているため、必要ありません。ただし、実際のアプリでは、ViewModel などと通信してビジネス ロジックを実行します。

続いて、ボタン内にアイコンを設定します。このコードは、以前に Icon で見たものと同じです。また、アイコンは androidx.compose.material:material-icons-extended ライブラリから取得しています。

最後に、先ほど設定したアイコンの修飾子を設定します。

アプリを実行すると、次のように表示されます。

f9fce435c935d610.png

このコードは、以前に記述した(優れた)コードであると考えられます。違いは、Wear OS 向けに最適化されたボタンが表示されるようになった点です。

これは非常に簡単なことです。別の問題を見てみましょう。

テキスト コンポーザブルを作成する

ReusableComponents.kt で「TODO: Create a Text Composable」を検索して、現在のコンポーザブル メソッドを次のコードに置き換えます。

ステップ 3

// TODO: Create a Text Composable
@Composable
fun TextExample(modifier: Modifier = Modifier) {
    Text(
        modifier = modifier,
        textAlign = TextAlign.Center,
        color = MaterialTheme.colors.primary,
        text = stringResource(R.string.device_shape)
    )
}

Text コンポーザブルの作成、修飾子の設定、テキストの配置、色の設定を行い、最後に String リソースからテキスト自体を設定します。

テキスト コンポーザブルの外観は Compose のデベロッパーにはなじみがあり、実際のコードはモバイル側でも同一です。

どのように表示されるかを確認してみましょう。

52a4e318d12d7ba5.png

TextExample() コンポーズ可能な関数(コードを配置した場所)が、メインのマテリアル カラーのテキスト コンポーザブルを生成するようになりました。

この文字列は res/values/strings.xml ファイルから取得されます。実際には、res/values フォルダには 2 つの strings.xml リソース ファイルがあります。

Wear OS には、円形と円形以外のデバイス向けの文字列リソースが用意されているため、正方形のエミュレータで実行すると、文字列が変化します。

27e50afef57b7717.png

ここまでは順調です。最後に最も近いコンポーザブル Card を見てみましょう。

カード コンポーザブルを作成する

ReusableComponents.kt で「TODO: Create a Card」を検索して、現在のコンポーザブル メソッドを次のコードに置き換えます。

ステップ 4

// TODO: Create a Card (specifically, an AppCard) Composable
@Composable
fun CardExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    AppCard(
        modifier = modifier,
        appImage = {
            Icon(
                imageVector = Icons.Rounded.Message,
                contentDescription = "triggers open message action",
                modifier = iconModifier
            )
        },
        appName = { Text("Messages") },
        time = { Text("12m") },
        title = { Text("Kim Green") },
        onClick = { /* ... */ }
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            Text("On my way!")
        }
    }
}

Wear は、AppCardTitleCard という 2 つの主要なカードが用意されている点で若干異なります。

このケースでは、Icon をカードに配置する必要があるため、AppCard を使用します(TitleCard はテキストにのみフォーカスします)。

AppCard コンポーザブルの作成、修飾子の設定、Icon の追加、いくつかの Text コンポーザブル パラメータの追加(カード上の異なるスペースにそれぞれ追加)を行い、最後にメイン コンテンツ テキストを末尾に設定します。

どのように表示されるかを確認してみましょう。

dcb5e5bebf9f19d9.png

この時点で、これらのコンポーザブルの Compose コードはモバイルとほぼ同じであることにお気づきでしょう。これはすばらしいことです。すでに獲得した知識を再利用できます。

新しいコンポーザブルを見てみましょう。

6. Wear の一意のコンポーザブルを追加する

このセクションでは、Chip コンポーザブルと ToggleChip コンポーザブルについて見ていきます。

チップ コンポーザブルを作成する

チップは実際にはマテリアル ガイドラインで指定されますが、モバイル マテリアル ライブラリに実際にコンポーズ可能な関数はありません。

チップはタップ 1 回で簡単に操作できるように設計されており、画面の表示スペースが限られている Wear デバイスに特に適しています。

コンポーズ可能な関数 Chip のバリエーションを以下にいくつか紹介します。これを使用して作成してみましょう。

まずは、コードを記述してみましょう。

ReusableComponents.kt で「TODO: Create a Chip」を検索して、現在のコンポーザブル メソッドを次のコードに置き換えます。

ステップ 5

// TODO: Create a Chip Composable
@Composable
fun ChipExample(
    modifier: Modifier = Modifier,
    iconModifier: Modifier = Modifier
) {
    Chip(
        modifier = modifier,
        onClick = { /* ... */ },
        label = {
            Text(
                text = "5 minute Meditation",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        },
        icon = {
            Icon(
                imageVector = Icons.Rounded.SelfImprovement,
                contentDescription = "triggers meditation action",
                modifier = iconModifier
            )
        },
    )
}

Chip コンポーザブルは、他のコンポーザブル(修飾子と onClick)で使用されているものと同じ多くのパラメータを使用するため、確認する必要はありません。

また、ラベル(Text コンポーザブルを作成します)とアイコンも受け取ります。

Icon のコードは、他のコンポーザブルに表示されたコードとまったく同じに見えますが、今回は androidx.compose.material:material-icons-extended ライブラリから Self Improvement アイコンを取得しています。

どのように表示されるか確認してみましょう(下にスクロールしてください)。

77bde81f8f290f87.png

では、ToggleChip コンポーザブルである Toggle のバリエーションを見てみましょう。

ToggleChip コンポーザブルを作成する

ToggleChipChip に非常に類似していますが、ラジオボタン、トグル、チェックボックスの操作が可能です。

ReusableComponents.kt で「TODO: Create a ToggleChip」を検索して、現在のコンポーザブル メソッドを次のコードに置き換えます。

ステップ 6

// TODO: Create a ToggleChip Composable
@Composable
fun ToggleChipExample(modifier: Modifier = Modifier) {
    var checked by remember { mutableStateOf(true) }
    ToggleChip(
        modifier = modifier,
        checked = checked,
        toggleIcon = {
            ToggleChipDefaults.SwitchIcon(checked = checked)
        },
        onCheckedChange = {
            checked = it
        },
        label = {
            Text(
                text = "Sound",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    )
}

(このコードが存在する)ToggleChipExample() コンポーズ可能な関数が、チェックボックスまたはラジオボタンではなくトグルを使用して ToggleChip を生成するようになりました。

まず、MutableState を作成します。他の関数では、この操作を行っていません。Wear で提供されている機能を確認できるように、UI のデモを中心に行っているためです。

通常のアプリでは、コンポーザブルをステートレスにするために、オンにされた状態とタップを処理するラムダを渡す必要があります(詳細については、こちらをご覧ください)。

今回は、トグルを使用した ToggleChip の動作を簡単に確認するだけであるため、シンプルにします(状態とは何も関係ありません)。

次に、修飾子、オンにされた状態、切り替えアイコンを設定して、必要な切り替えを行います(今回はデフォルトを使用します)。

続いて、状態を変更するラムダを作成し、ラベルに Text コンポーザブル(およびいくつかの基本的なパラメータ)を設定します。

どのように表示されるかを確認してみましょう。

b76b501e91a64969.png

ここまで多くの Wear OS 固有のコンポーザブルを見てきました。前述のとおり、コードの大部分はモバイルで記述しているものとほぼ同じです。

もう少し高度な方法を見てみましょう。

7. ScalingLazyColumn に移行する

モバイルアプリで縦方向にスクロールするリストを作成するために、LazyColumn を利用したことがあるかもしれません。

円形のデバイスは上部と下部が小さいため、アイテムを表示するスペースが少なくなります。そのため、Wear OS には独自のバージョンの LazyColumn があり、こうした円形のデバイスに対するサポートを強化します。

ScalingLazyColumn が画面の上部と下部の拡張性と透明性の両方をサポートするよう LazyColumn を拡張することで、ユーザーにとってのコンテンツの判読性を高められます。

次のデモをご覧ください。

28460354eaf16eea.gif

アイテムが中央に近づくとフルサイズにまで拡大し、中央から離れると縮小して透明性が向上します。

アプリの具体的な例を次に示します。

307c969dccf58e49.gif

これは、読みやすさに特に役立っています。

ScalingLazyListState の動作を確認したところで、LazyColumn の変換を開始しましょう。

ScalingLazyListState に変換する

MainActivity.kt で「TODO: Swap to ScalingLazyListState」を検索し、そのコメントと下の行を次のコードに置き換えます。

ステップ 7

// TODO: Swap to ScalingLazyListState
val listState = rememberScalingLazyListState()

名前は、「Scaling」の部分を除いてほぼ同じです。LazyListStateLazyColumn の状態を処理するのと同じように、ScalingLazyListStateScalingLazyColumn の状態を処理します。

ScalingLazyColumn に変換する

次に、ScalingLazyColumn でスワップします。

MainActivity.kt で「TODO: Swap a ScalingLazyColumn」を検索し、その行と下の行を次のコードに置き換えます。

ステップ 8

        // TODO: Swap a ScalingLazyColumn (Wear's version of LazyColumn)
        ScalingLazyColumn(

これで完了です。どのように表示されるかを確認してみましょう。

264ab059418a6526.png

スクロールする手間をほとんどかけずに、画面上部と下部でコンテンツがスケーリングされ、透明度が調整されます。

メディテーション コンポーザブルを上下に動かすと、この動作を確認できます。

最後のトピックである Wear OS の Scaffold をご覧ください。

8. Scaffold を追加する

Scaffold には、アプリバー、FAB、ドロワー、その他のモバイル固有の要素ではなく、モバイルと同様に一般的なパターンで画面を配置するためのレイアウト構造が用意されています。トップレベル コンポーネント(時間、周辺減光、スクロール / 位置インジケーター)を備えた 3 つの Wear 固有のレイアウトをサポートします。

また、円形と円形以外のデバイスのどちらも処理します。

表示例を次に示します。

TimeText

Vignette

PositionIndicator

各コンポーネントの詳細を確認しますが、まずは Scaffold を配置します。

Scaffold を追加する

Scaffold のボイラープレートを追加してみましょう。

TODO (Start): Create a Scaffold (Wear Version)」を検索して、その下に次のコードを追加します。

ステップ 9

// TODO (Start): Create a Scaffold (Wear Version)
Scaffold(
    timeText = { },
    vignette = { },
    positionIndicator = { }
) {

これらのパラメータについては、後のステップで順に説明します。現時点では、UI は作成されていません。

正しい位置に右かっこを追加します。「TODO (End): Create a Scaffold (Wear Version)」を検索してかっこを追加します。

ステップ 10

// TODO (End): Create a Scaffold (Wear Version)
}

まずこれを実行しましょう。次のように表示されます。

2ddc667e07d8f04c.png

Scaffold を追加しても動作はこれまでと変わりませんが、コンポーネントの実装を開始すると変化します。

3 つのパラメータの最初の TimeText から見てみましょう。

TimeText

TimeText は内部で曲線テキストを使用するため、デベロッパーは、コンポーザブルを配置する、または時刻関連のクラスを扱う必要なく、時刻を簡単に表示できます。

マテリアル ガイドラインでは、オーバーレイ(またはアプリ)のどの画面でも上部に時刻を表示するよう求めています。たとえば、次のように表示される必要があります。

29671ae0a7c3225b.png

TimeText の追加はとても簡単です。

timeText = { },」を検索して、次のコードに置き換えます。

ステップ 11

timeText = {
    if (!listState.isScrollInProgress) {
        TimeText()
    }
},

ユーザーがスクロールを開始したときに時刻を非表示にするロジックを、いくつか追加しました。

その後、TimeText コンポーザブルを作成するだけです。パラメータを追加して、時刻の前後にテキストを追加することもできますが、シンプルにします。

実行してみてください。時刻が表示されますが、スクロールすると非表示になります。

896aaebb9a89bbe8.png

次に、Vignette について説明します。

周辺減光を追加する

Vignette はスクロール可能な画面が表示されているときに、ウェアラブル画面の上端と下端をぼかします。

デベロッパーは、ユースケースに応じて上端、下端、または両方をぼかすことができます。

次の例をご覧ください。

689ac8becaac6824.png

画面が 1 つ(スクロール可能な画面)であるため、周辺減光された状態の表示により判読性を改善しようと考えています。それでは、そのための操作を行います。

vignette = { },」を検索して、次のコードに置き換えます。

ステップ 12

vignette = {
    // Only show a Vignette for scrollable screens. This code lab only has one screen,
    // which is scrollable, so we show it all the time.
    Vignette(vignettePosition = VignettePosition.TopAndBottom)
},

周辺減光された状態で表示すべき場合とすべきでない場合について詳しくは、コメントをご覧ください。今回は、常に周辺減光された状態で表示するようにし、画面の上部と下部の両方をぼかし処理します。

9a91313e5d59f49e.png

上部または下部(特に紫色のコンポーザブル)を見ると、効果を確認できます。

仕上げに、Scaffold の最後のパラメータ PositionIndicator を見ていきましょう。

PositionIndicator を追加する

PositionIndicator(スクロール インジケーター)は画面右側のインジケーターであり、渡す状態オブジェクトの種類に基づいて現在のインジケーターの場所を示します。ここでは ScalingLazyListState にします。

次の例をご覧ください。

181b19b55ce37251.png

さっそく始めましょう

特に注意深くご覧になっている方は、Scaffold の上に ScalingLazyListStateホイスティングしたことにお気づきでしょう。

ScalingLazyColumn より少し高い位置にホイスティングすることも可能である状況で、このような位置にホイスティングすることを疑問に思われたかもしれません。

画面の湾曲によって、位置インジケーターはビューポートの中心ではなく、時計の中心に配置する必要があります。そのように処理しないと、見切れる可能性があります。

たとえば、以下のアプリでは、「Playlist」コンポーザブルはスクロール可能領域に収まっていないと想定できます。

c9f96a90a3e811fb.png

位置インジケーターが(この場合のように)画面の中心に配置されておらず、リストのビューポートの中心に配置されている場合は、画面が円形であるために大部分が見切れます。つまり、画面の範囲外です。

なぜ画面のそれほど高い位置にホイスティングするのかについての説明を終えたところで、インジケーターをアプリに追加しましょう。

positionIndicator = { }」を検索して、次のコードに置き換えます。

ステップ 12

positionIndicator = {
    PositionIndicator(
        scalingLazyListState = listState
    )
}

これは極めて単純であり、PositionIndicator は自身を適切にレンダリングするためにスクロール状態を必要とします(その処理は可能になりました)。

ユーザーがスクロールしていないときに、自身を非表示にできる優れた機能も備えています。

ScalingLazyListState を使用していますが、PositionIndicator は他にも多数のスクロール オプション(例: ScrollStateLazyListState。さらに回転するサイドボタンまたは

回転ベゼルの処理も可能)を受け取ります。すべてのオプションについては、各バージョンの KDocs で確認してください

では、確認しましょう。

8c278b78ab008cbb.png

上下にスクロールしてみます。スクロール インジケーターは、スクロール中にのみ表示されます。

これで、ほとんどの Wear OS コンポーザブルの UI デモは完了です。

9. 完了

これで、Wear OS で Compose を使用する際の基本についての学習が完了しました。

モバイルの知識をすべて再活用して、美しい Wear OS アプリの作成を開始できます。

次のステップ

Wear OS の他の Codelab をご確認ください。

参考資料