柔軟なウィジェット レイアウトを提供する

このページでは、ウィジェットのサイズ変更と柔軟性の向上について説明します。 Android 12(API レベル 31)で導入されました。また、kubectl の ウィジェットのサイズを決定します

改良された API を使用してウィジェットのサイズとレイアウトを設定する

Android 12(API レベル 31)以降では、より細かいサイズを指定できます。 柔軟なレイアウトを使用できます。 以降のセクションで説明します。

  1. ウィジェットのサイズに関する追加の制約を指定します。

  2. レスポンシブ レイアウトまたは正確なレイアウト 説明します

以前のバージョンの Android では、ビューのサイズ範囲は ウィジェットを OPTION_APPWIDGET_MIN_WIDTH OPTION_APPWIDGET_MIN_HEIGHT, OPTION_APPWIDGET_MAX_WIDTH, および OPTION_APPWIDGET_MAX_HEIGHT ウィジェットのサイズを推定しますが、このロジックは 対応できます。Android 12 以降をターゲットとするウィジェットの場合は、 レスポンシブまたは正確な レイアウトをご覧ください。

ウィジェットのサイズ調整に関する追加の制約を指定する

Android 12 では、ウィジェットが 各種の画面サイズの各種デバイスに対応して、より確実にサイズを調整できます。

既存の minWidthminHeightminResizeWidthminResizeHeight 属性に加えて、次の新しい appwidget-provider 属性を使用します。

  • targetCellWidth および targetCellHeight: ランチャーのグリッドのセルで、ウィジェットのターゲット サイズを定義します。定義されている場合は、minWidthminHeight の代わりにこれらの属性が使用されます。

  • maxResizeWidth および maxResizeHeight: ランチャーでユーザーがウィジェットのサイズを変更できる最大サイズを定義します。

次の XML は、サイズ設定属性の使用方法を示しています。

<appwidget-provider
  ...
  android:targetCellWidth="3"
  android:targetCellHeight="2"
  android:maxResizeWidth="250dp"
  android:maxResizeHeight="110dp">
</appwidget-provider>

レスポンシブ レイアウトを提供する

ウィジェットのサイズに応じてレイアウトを変更する必要がある場合は、さまざまなサイズに対して有効な、少数のレイアウトを作成することをおすすめしますもし ウィジェットを元にしたレイアウトを提供するという方法もあります。 実行時のサイズを指定します(このページで説明します)。

この機能により、よりスムーズなスケーリングとシステム全体の システムが毎回アプリを復帰させる必要がなくなるため、 ウィジェットのサイズが変わります。

次のコードサンプルは、レイアウトのリストを提供する方法を示しています。

Kotlin

override fun onUpdate(...) {
    val smallView = ...
    val tallView = ...
    val wideView = ...

    val viewMapping: Map<SizeF, RemoteViews> = mapOf(
            SizeF(150f, 100f) to smallView,
            SizeF(150f, 200f) to tallView,
            SizeF(215f, 100f) to wideView
    )
    val remoteViews = RemoteViews(viewMapping)

    appWidgetManager.updateAppWidget(id, remoteViews)
}

Java

@Override
public void onUpdate(...) {
    RemoteViews smallView = ...;
    RemoteViews tallView = ...;
    RemoteViews wideView = ...;

    Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>();
    viewMapping.put(new SizeF(150f, 100f), smallView);
    viewMapping.put(new SizeF(150f, 200f), tallView);
    viewMapping.put(new SizeF(215f, 100f), wideView);
    RemoteViews remoteViews = new RemoteViews(viewMapping);

    appWidgetManager.updateAppWidget(id, remoteViews);
}

ウィジェットに以下の属性があるとします。

<appwidget-provider
    android:minResizeWidth="160dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="200dp">
</appwidget-provider>

上記のコード スニペットは、次のことを意味します。

  • smallView は 160 dp(minResizeWidth)× 110 dp をサポートします (minResizeHeight)を 160 dp × 199 dp(次のカットオフ ポイント - 1 dp)に変更します。
  • tallView は、160 dp × 200 dp ~ 214 dp(次のカットオフ ポイント - 1)× をサポートします。 200 dp。
  • wideView は、215 dp × 110 dp(minResizeHeight)~ 250 dp をサポートします。 (maxResizeWidth)× 200 dp(maxResizeHeight)。

ウィジェットは minResizeWidth × のサイズ範囲をサポートする必要があります minResizeHeightmaxResizeWidth × maxResizeHeight。この範囲内で レイアウトを切り替えるカットオフ ポイントを決定できます。

レスポンシブ レイアウトの例
図 1. レスポンシブ レイアウトの例。

正確なレイアウトを提供する

少数のレスポンシブ レイアウトを提供できない場合は、ウィジェットを表示するサイズに合わせてさまざまなレイアウトを提供できます。これは通常、スマートフォン用の 2 つのサイズ(縦向きと横向き)と、折りたたみ式デバイス用の 4 つのサイズで構成されます。

このソリューションを実装するには、アプリで次の手順を行う必要があります。

  1. サイズセットが変更されたときに呼び出される AppWidgetProvider.onAppWidgetOptionsChanged() をオーバーロードします。

  2. サイズを含む Bundle を返す AppWidgetManager.getAppWidgetOptions() を呼び出します。

  3. Bundle から AppWidgetManager.OPTION_APPWIDGET_SIZES キーにアクセスします。

次のコードサンプルは、正確なレイアウトを提供する方法を示しています。

Kotlin

override fun onAppWidgetOptionsChanged(
        context: Context,
        appWidgetManager: AppWidgetManager,
        id: Int,
        newOptions: Bundle?
) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions)
    // Get the new sizes.
    val sizes = newOptions?.getParcelableArrayList<SizeF>(
            AppWidgetManager.OPTION_APPWIDGET_SIZES
    )
    // Check that the list of sizes is provided by the launcher.
    if (sizes.isNullOrEmpty()) {
        return
    }
    // Map the sizes to the RemoteViews that you want.
    val remoteViews = RemoteViews(sizes.associateWith(::createRemoteViews))
    appWidgetManager.updateAppWidget(id, remoteViews)
}

// Create the RemoteViews for the given size.
private fun createRemoteViews(size: SizeF): RemoteViews { }

Java

@Override
public void onAppWidgetOptionsChanged(
    Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
    // Get the new sizes.
    ArrayList<SizeF> sizes =
        newOptions.getParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES);
    // Check that the list of sizes is provided by the launcher.
    if (sizes == null || sizes.isEmpty()) {
      return;
    }
    // Map the sizes to the RemoteViews that you want.
    Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>();
    for (SizeF size : sizes) {
        viewMapping.put(size, createRemoteViews(size));
    }
    RemoteViews remoteViews = new RemoteViews(viewMapping);
    appWidgetManager.updateAppWidget(id, remoteViews);
}

// Create the RemoteViews for the given size.
private RemoteViews createRemoteViews(SizeF size) { }

ウィジェットのサイズを決定する

各ウィジェットでデバイスの targetCellWidthtargetCellHeight を定義する必要があります。 Android 12 以降、またはすべての minWidthminHeight 最小消費容量、最小使用容量、最小使用容量、 できます。ただし、ユーザーがホーム画面にウィジェットを追加すると、 指定した最小の幅と高さよりも大きくなります。

Android のホーム画面には、利用可能なスペースのグリッドが表示され、ユーザーは 場所ウィジェットとアイコンですこのグリッドはデバイスによって異なります。たとえば、 スマートフォンは 5x4 のグリッド、タブレットはより大きなグリッドで表示されます。ウィジェットが 最小のセル数を占有するように引き伸ばされ、 水平方向と垂直方向のスケーラビリティを兼ね備え、 targetCellWidthtargetCellHeight(実行中のデバイス) Android 12 以降、または minWidth 制約と minHeight 制約 Android 11(API レベル 30)以前を搭載したデバイス

セルの幅と高さ、適用された自動余白のサイズの両方 デバイスによって異なる場合があります次の表を使用しておおまかに見積もります。 典型的な 5x4 グリッドのハンドセットにおけるウィジェットの最小寸法は、 占有するグリッドセルの数:

セル数(幅 x 高さ) 縦表示で利用可能なサイズ(dp) 横表示で利用可能なサイズ(dp)
1×1 57x102dp 127x51dp
2×1 130x102dp 269x51dp
3×1 203x102dp 412x51dp
4x1 276x102dp 554x51dp
5×1 349x102dp 697x51dp
5×2 349x220dp 697x117dp
5×3 349x337dp 697x184dp
5×4 349x455dp 697x250dp
... ... ...
n×m (73n - 16)×(118m - 16) (142n - 15)×(66m - 15)

ポートレート モードのセルサイズを使用して、 minWidthminResizeWidthmaxResizeWidth の各属性。同様に 横表示のセルサイズを使用して、指定する値を通知します。 minHeightminResizeHeightmaxResizeHeight 属性。

これは、通常、ポートレート モードではセル幅が小さくなるためです。 セルの高さは通常、横表示よりも高くなります。 横表示は縦表示よりも小さくなります

たとえば、ウィジェットの幅を Google Pixel の 1 つのセルまでサイズ変更可能にする場合、 Google Pixel 4 の場合は、minResizeWidth を 56 dp 以下に設定する必要があります minResizeWidth 属性の値を小さくするようにします。 セルの幅が縦向きで 57 dp 以上であるため。 同様に、画面上の 1 つのセルでウィジェットの高さをサイズ変更可能にする場合は、 使用する場合は、minResizeHeight を 50 dp 以下に設定して、 minResizeHeight 属性の値が次の値より小さい 51 dp - 横表示の場合、1 つのセルの高さが 51 dp 以上であるため。

各ウィジェットは、 minResizeWidth/minResizeHeightmaxResizeWidth/maxResizeHeight 属性があるため、それらの間の任意のサイズ範囲に適応する必要があります。

たとえば、プレースメントでのウィジェットのデフォルト サイズを設定するには、 次の属性を設定します。

<appwidget-provider
    android:targetCellWidth="3"
    android:targetCellHeight="2"
    android:minWidth="180dp"
    android:minHeight="110dp">
</appwidget-provider>

つまり、ウィジェットのデフォルト サイズは 3x2 セルです。これは targetCellWidth 属性と targetCellHeight 属性、または 180 × 110 dp( (minWidthminHeight で指定されたデバイス用) Android 11 以前。後者の場合、セルのサイズを はデバイスによって異なります。

また、ウィジェットでサポートされているサイズ範囲を設定するには、 属性:

<appwidget-provider
    android:minResizeWidth="180dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="530dp"
    android:maxResizeHeight="450dp">
</appwidget-provider>

前述の属性で指定されているとおり、ウィジェットの幅は 180 dp から 530 dp にサイズ変更可能で、高さは 110 dp から 450 dp までサイズ変更可能です。 ウィジェットは、次の条件を満たす限り、3x2 セルから 5x2 セルにサイズ変更できます。 条件が存在する場合:

  • デバイスは 5x4 グリッドです。
  • セル数と使用可能なサイズのマッピング(dps) ディメンションをご覧ください。
  • ウィジェットはそのサイズ範囲に適応します。

Kotlin

val smallView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_small)
val mediumView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_medium)
val largeView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_large)

val viewMapping: Map<SizeF, RemoteViews> = mapOf(
        SizeF(180f, 110f) to smallView,
        SizeF(270f, 110f) to mediumView,
        SizeF(270f, 280f) to largeView
)

appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(viewMapping))

Java

RemoteViews smallView = 
    new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_small);
RemoteViews mediumView = 
    new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_medium);
RemoteViews largeView = 
    new RemoteViews(context.getPackageName(), R.layout.widget_weather_forecast_large);

Map<SizeF, RemoteViews> viewMapping = new ArrayMap<>();
viewMapping.put(new SizeF(180f, 110f), smallView);
viewMapping.put(new SizeF(270f, 110f), mediumView);
viewMapping.put(new SizeF(270f, 280f), largeView);
RemoteViews remoteViews = new RemoteViews(viewMapping);

appWidgetManager.updateAppWidget(id, remoteViews);

ウィジェットは、前のスライドで定義したレスポンシブ レイアウトを使用していると仮定します。 コードスニペットを作成しますつまり、terraform plan または terraform apply の R.layout.widget_weather_forecast_small が 180 dp(minResizeWidth)x から使用されています 110 dp(minResizeHeight)~ 269 x 279 dp(次のカットオフ ポイント - 1)同様に 270x110 dp ~ 270x279 dp の R.layout.widget_weather_forecast_medium が使用されます。 R.layout.widget_weather_forecast_large が 270x280 dp から 530 dp(maxResizeWidth)x 450 dp(maxResizeHeight)。

ユーザーがウィジェットのサイズを変更すると、それに合わせてデザインも変化します。 各セルに展開されます。

最小の 3x2 グリッドサイズの天気ウィジェットの例。UI には
            場所の名前(東京)、気温(14°)、場所を示す記号
            ところにより曇りです。
図 2. 3x2 R.layout.widget_weather_forecast_small

4x2 の「medium」の天気ウィジェットの例指定します。ウィジェットのサイズを変更する
            以前のウィジェットサイズから
すべての UI を基盤にしています
            「おおむね曇り」というラベルが追加されます天気予報、
            午後 4 時から午後 7 時まで。
図 3. 4x2 R.layout.widget_weather_forecast_medium

<ph type="x-smartling-placeholder">
</ph> 5x2 の「medium」の天気ウィジェットの例指定します。ウィジェットのサイズを変更する
            その結果、UI は前のサイズと同じになりますが、
            1 つのセル長だけ引き伸ばされ、より多くの水平方向のスペースを占めます。
図 4.5x2 R.layout.widget_weather_forecast_medium

5x3 の「large」の天気ウィジェットの例指定します。ウィジェットのサイズを変更する
            以前のウィジェットサイズと同じ
UI を基盤にしています
            天気予報を表示するビューをウィジェット内に追加します
            表示されます晴れまたは雨を示す記号
            日ごとの最高気温と最低気温を確認できます。
図 5. 5x3 R.layout.widget_weather_forecast_large

5x4 の「large」の天気ウィジェットの例指定します。ウィジェットのサイズを変更する
            以前のウィジェットサイズと同じ
UI を基盤にしています
            木曜日と金曜日(および対応する記号)を追加します
            天気の種類、最高気温、最低気温を示します
            。
図 6. 5x4 R.layout.widget_weather_forecast_large