本頁說明 Android 12 (API 級別 31) 中引入的小工具尺寸調整功能及更豐富的彈性。以及如何決定小工具的大小。
針對小工具大小和版面配置使用改良版 API
從 Android 12 (API 級別 31) 開始,您可以按照下列步驟提供更精細的大小屬性和彈性版面配置,如後續章節所述:
在舊版 Android 中,您可以使用 OPTION_APPWIDGET_MIN_WIDTH
、OPTION_APPWIDGET_MIN_HEIGHT
、OPTION_APPWIDGET_MAX_WIDTH
和 OPTION_APPWIDGET_MAX_HEIGHT
額外項目取得小工具的大小範圍,然後估算小工具的大小,但該邏輯並非在所有情況下都能正常運作。針對指定 Android 12 以上版本的小工具,建議您提供回應式或確切版面配置。
指定其他小工具大小限制
Android 12 新增了 API,可讓您針對各種螢幕大小,為各種裝置提供更可靠的小工具大小。
除了現有的 minWidth
、minHeight
、minResizeWidth
和 minResizeHeight
屬性之外,請使用下列新的 appwidget-provider
屬性:
targetCellWidth
和targetCellHeight
:根據啟動器格線儲存格定義小工具的目標大小。如已定義,系統會使用這些屬性,而不是minWidth
或minHeight
。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
支援 160dp (minResizeWidth
) × 110dp (minResizeHeight
) 到 160dp × 199dp (下一個截止點 - 1dp)。tallView
支援 160dp × 200dp 到 214 dp (下一個截止點 - 1) × 200dp。wideView
支援 215dp × 110dp (minResizeHeight
) 到 250 dp (maxResizeWidth
) × 200dp (maxResizeHeight
)。
小工具必須支援介於 minResizeWidth
× minResizeHeight
到 maxResizeWidth
× maxResizeHeight
的大小範圍。在這個範圍內,您可以決定要切換版面配置的截斷點。
![回應式版面配置範例](https://developer.android.google.cn/static/images/appwidgets/size-range.gif?authuser=3&hl=zh-tw)
提供確切的版面配置
如果一小部分的回應式版面配置不適用,您可以改為針對小工具顯示的大小,提供不同的版面配置。這類裝置通常有兩種尺寸 (直向和橫向模式),而折疊式裝置則為四種尺寸。
如要實作這項解決方案,應用程式必須執行下列步驟:
在一組大小變更時呼叫
AppWidgetProvider.onAppWidgetOptionsChanged()
。呼叫
AppWidgetManager.getAppWidgetOptions()
,以傳回包含大小的Bundle
。從
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) { }
決定小工具的大小
每個小工具都必須為搭載 Android 12 以上版本的裝置定義 targetCellWidth
和 targetCellHeight
,針對所有 Android 版本定義 minWidth
和 minHeight
,表示預設使用的空間下限。不過,當使用者在主畫面中新增小工具時,系統通常會佔據您指定的最小寬度和高度。
Android 主畫面會以格狀檢視畫面呈現可用空間,方便使用者在其中放置小工具和圖示。網格可能因裝置而異;例如,許多手機提供 5x4 的格狀空間,平板電腦則可提供更大的格狀。新增小工具後,系統會進行延展,填滿儲存格數量下限 (水平和垂直),在搭載 Android 12 以上版本的裝置上,達到 targetCellWidth
和 targetCellHeight
的限制。在搭載 Android 11 (API 級別 30) 以下版本的裝置上,則為 minWidth
和 minHeight
限制條件。
儲存格的寬度和高度,以及套用至小工具的自動邊界大小可能因裝置而異。請使用下表,根據您所需要的格線儲存格數量,以一般 5x4 方格手機大致估算小工具的最小尺寸:
儲存格數量 (寬度 x 高度) | 直向模式的可用大小 (dp) | 橫向模式的可用大小 (dp) |
---|---|---|
1x1 | 57x102dp | 127x51dp |
2x1 | 130x102dp | 269x51dp |
3x1 | 203x102dp | 412x51dp |
4x1 | 276x102dp | 554x51dp |
5x1 | 349x102dp | 697x51dp |
5x2 | 349x220dp | 697x117dp |
5x3 | 349x337dp | 697x184dp |
5x4 | 349x455dp | 697x250dp |
... | ... | ... |
n x m | (73n - 16) x (118 分鐘 - 16) | (142n - 15) x (66 分鐘 - 15) |
請使用直向模式儲存格大小,告知您為 minWidth
、minResizeWidth
和 maxResizeWidth
屬性提供的值。同樣地,您也可以使用橫向模式儲存格大小,告知您為 minHeight
、minResizeHeight
和 maxResizeHeight
屬性提供的值。
這是因為在直向模式下,儲存格的寬度通常會小於橫向模式,同樣地,在橫向模式下,儲存格的高度通常會比直向模式小。
舉例來說,如果您想在 Google Pixel 4 上將小工具寬度調整為單一儲存格,請將 minResizeWidth
設為最多 56dp,以確保 minResizeWidth
屬性的值小於 57dp,因為儲存格的直向寬度至少為 57dp。同樣地,如果您想在同一裝置的某個儲存格中調整小工具高度,必須將 minResizeHeight
設為最多 50dp,以確保 minResizeHeight
屬性的值小於 51dp,因為在橫向模式下,其中一個儲存格的高度至少為 51dp。
每個小工具都可以在 minResizeWidth
/minResizeHeight
和 maxResizeWidth
/maxResizeHeight
屬性之間的大小範圍內調整大小,因此必須配合兩者之間的任何大小範圍進行調整。
舉例來說,如要設定刊登位置上的小工具預設大小,您可以設定下列屬性:
<appwidget-provider
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
也就是說,根據 targetCellWidth
和 targetCellHeight
屬性指定,小工具的預設大小為 3x2 儲存格,或 180×110dp,如 minWidth
和 minHeight
所指定,搭載 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 的方格。
- 儲存格數量與可用大小 (以 dp 為單位) 的對應關係遵循本頁的最小維度估算結果。
- 小工具會配合該大小範圍進行調整。
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);
假設小工具使用上述程式碼片段中定義的回應式版面配置。也就是說,指定為 R.layout.widget_weather_forecast_small
的版面配置會使用 180dp (minResizeWidth
) x 110dp (minResizeHeight
) 到 269x279dp (下一個截止點 - 1)。同樣地,R.layout.widget_weather_forecast_medium
使用範圍從 270x110 dp 到 270x279 dp,R.layout.widget_weather_forecast_large
則用於 270x280 dp 到 530dp (maxResizeWidth
) x 450dp (maxResizeHeight
)。
當使用者調整小工具大小時,外觀會隨儲存格的大小而改變,如以下範例所示。
![範例:以 3x2 方格尺寸最小的天氣小工具。使用者介面會顯示位置名稱 (東京)、溫度 (14°),以及表示部分天氣不佳的符號。](https://developer.android.google.cn/static/images/appwidgets/weather-size-3x2.png?authuser=3&hl=zh-tw)
R.layout.widget_weather_forecast_small
。![以 4x2「中」尺寸顯示天氣小工具的範例。以這種方式調整小工具大小時,會以先前的小工具大小為依據,並新增「最多雲」標籤,並新增「最多雲」標籤,以及下午 4 點到晚上 7 點的氣溫預測。](https://developer.android.google.cn/static/images/appwidgets/weather-size-4x2.png?authuser=3&hl=zh-tw)
R.layout.widget_weather_forecast_medium
。![以 5x2「中」尺寸顯示天氣小工具的範例。以這種方式調整小工具大小,將產生與先前大小相同的使用者介面,只不過會延伸一個儲存格長度,以佔用更多水平空間。](https://developer.android.google.cn/static/images/appwidgets/weather-size-5x2.png?authuser=3&hl=zh-tw)
R.layout.widget_weather_forecast_medium
。![以 5x3「大」尺寸顯示的天氣小工具範例。以這種方式調整小工具大小時,會以先前小工具大小的所有使用者介面為基礎,並在小工具中加入一個檢視畫面,提供週二和週三的天氣預報。表示每天晴天或多雨,以及高溫和低溫的符號。](https://developer.android.google.cn/static/images/appwidgets/weather-size-5x3.png?authuser=3&hl=zh-tw)
R.layout.widget_weather_forecast_large
。![範例:以 5x4 大尺寸呈現的天氣小工具。以這種方式調整小工具大小時,會以先前小工具大小的所有使用者介面為基礎,並新增星期四和星期五 (以及代表天氣類型以及每日高溫和低溫的對應符號)。](https://developer.android.google.cn/static/images/appwidgets/weather-size-5x4.png?authuser=3&hl=zh-tw)
R.layout.widget_weather_forecast_large
。