ウィジェットを強化する

Compose をお試しください
Jetpack Compose は、Android で推奨される UI ツールキットです。Compose スタイルの API を使用してウィジェットを構築する方法を学びます。

このページでは、Android 12(API レベル 31)以降で使用できるオプションのウィジェット拡張機能について詳しく説明します。これらの機能はオプションですが、簡単に実装でき、ユーザーのウィジェット エクスペリエンスを向上させることができます。

ウィジェットを拡張する方法については、Compose ガイドの ウィジェットを拡張するをご覧ください。

動的な色を使用する

Android 12 以降のウィジェットでは、ボタンや背景などのコンポーネントにデバイスモードの色を使用できます。これにより、ウィジェット間の遷移がスムーズになり、一貫性が保持されます。

動的な色を実現する方法は 2 つあります。

  • ルート レイアウトでシステムのデフォルト テーマ(@android:style/Theme.DeviceDefault.DayNight)を使用します。

  • Android 用マテリアル コンポーネント ライブラリからマテリアル 3 テーマ(Theme.Material3.DynamicColors.DayNight)を使用します。このライブラリは Android 用マテリアル コンポーネント v1.6.0 以降で使用できます。

ルート レイアウトでテーマを設定したら、ルートまたはその子で共通の色属性を使用して、動的な色を選択できます。

使用できる色属性の例を次に示します。

  • ?attr/primary
  • ?attr/primaryContainer
  • ?attr/onPrimary
  • ?attr/onPrimaryContainer

マテリアル 3 テーマを使用した次の例では、デバイスのテーマカラーは「紫がかった色」です。 図 1 と図 2 に示すように、アクセント カラーとウィジェットの背景はライトモードとダークモードに合わせて調整されます。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/colorPrimaryContainer"
    android:theme="@style/Theme.Material3.DynamicColors.DayNight">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:tint="?attr/colorPrimaryContainer"
        android:src="@drawable/ic_cloud" />

    <!-- Other widget content. -->

</LinearLayout>

ライトモード テーマのウィジェット
図 1.ライトテーマのウィジェット。
ダークモード テーマのウィジェット
図 2.ダークテーマのウィジェット。

動的な色の下位互換性

動的な色は、Android 12 以降を搭載したデバイスでのみ使用できます。以前のバージョンにカスタム テーマを提供するには、カスタムカラーと新しい修飾子(values-v31)を使用して、デフォルトのテーマ属性でデフォルトのテーマを作成します。

マテリアル 3 テーマを使用した例を次に示します。

/values/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight">
    <!-- Override default colorBackground attribute with custom color. -->
    <item name="android:colorBackground">@color/my_background_color</item>

    <!-- Add other colors/attributes. -->

  </style>
</resources>

/values-v31/styles.xml

<resources>
  <!-- Do not override any color attribute. -->
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight" />
</resources>

/layout/my_widget_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="?android:attr/colorBackground"
    android:theme="@style/MyWidgetTheme" />

音声サポートを有効にする

App Actions を使用すると、Google アシスタント に関連するユーザーの音声コマンドに応じてウィジェットを表示できます。組み込みインテント(BII)に応答するようにウィジェットを構成することで、Android や Android Auto などのアシスタント サーフェスにウィジェットを事前に表示できます。ユーザーは、アシスタントに表示された ウィジェットを ランチャーに固定して、今後のエンゲージメントを促すことができます。

たとえば、エクササイズ アプリのワークアウト サマリー ウィジェットを構成して、 BII をトリガーするユーザーの音声コマンドに対応できます。 GET_EXERCISE_OBSERVATION ユーザーが 「OK Google, 今週は ExampleApp で何マイル走った?」などのリクエストを行ってこの BII をトリガーすると、アシスタントにウィジェットが事前に表示されます。

ユーザー インタラクションのいくつかのカテゴリをカバーする BII が多数用意されているため、ほとんどすべての Android アプリで音声用のウィジェットを拡張できます。まず、 App Actions を Android ウィジェットと統合するをご覧ください。

スムーズな遷移を有効にする

Android 12 以降では、ユーザーがウィジェットからアプリを起動すると、ランチャーにより遷移がスムーズに行われます。

この改善されたトランジションを有効にするには、@android:id/background または android.R.id.background を使用して背景要素を指定します。

<!-- Top-level layout of the widget. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
</LinearLayout>

以前のバージョンの Android では、アプリで @android:id/background を使用しても問題ありませんが、無視されます。

RemoteViews のランタイム変更を使用する

Android 12 以降では、RemoteViews 属性のランタイム変更を可能にするいくつかの RemoteViews メソッドを利用できます。追加されたメソッドの完全なリストについては、RemoteViews API リファレンスをご覧ください。

次のコードサンプルは、これらのメソッドの使用方法をいくつか示しています。

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(
    R.id.progress, "setProgressTintList", createProgressColorStateList()
)

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(
    R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DIP
)