Na tej stronie opisujemy ulepszenia dotyczące rozmiaru widżetów i większą elastyczność wprowadzone w Androidzie 12 (poziom API 31). Znajdziesz w nim też informacje o tym, Określ rozmiar widżetu.
Używanie ulepszonych interfejsów API do obsługi rozmiarów i układów widżetów
Począwszy od Androida 12 (poziom interfejsu API 31) możesz udostępniać bardziej precyzyjny rozmiar atrybutów i układów elastycznych, wykonując opisane niżej czynności, następujące sekcje:
Za pomocą układów elastycznych lub ścisłych układy.
W poprzednich wersjach Androida można uzyskać zakresy rozmiarów jako
za pomocą funkcji
OPTION_APPWIDGET_MIN_WIDTH
OPTION_APPWIDGET_MIN_HEIGHT
,
OPTION_APPWIDGET_MAX_WIDTH
,
oraz OPTION_APPWIDGET_MAX_HEIGHT
a potem oszacować rozmiar widżetu, ale to nie działa
w różnych sytuacjach. W przypadku widżetów kierowanych na Androida 12 lub nowszego zalecamy
podając elastyczne lub dokładniejsze informacje
układy scalone.
Określ dodatkowe ograniczenia rozmiaru widżetów
Android 12 dodaje interfejsy API, dzięki którym możesz mieć pewność, że widżet w bardziej odpowiedni sposób na różnych urządzeniach o różnych rozmiarach ekranów.
Oprócz istniejących funkcji minWidth
minHeight
,
minResizeWidth
,
oraz minResizeHeight
użyj tych nowych atrybutów appwidget-provider
:
targetCellWidth
itargetCellHeight
: określić docelowy rozmiar widżetu w postaci komórek siatki programu uruchamiającego. Jeśli te atrybuty są używane zamiast atrybutówminWidth
iminHeight
.maxResizeWidth
imaxResizeHeight
: określić maksymalny rozmiar widżetu, na jaki pozwala program uruchamiający – jego rozmiar.
Poniższy kod XML pokazuje, jak korzystać z atrybutów dobierania rozmiaru.
<appwidget-provider
...
android:targetCellWidth="3"
android:targetCellHeight="2"
android:maxResizeWidth="250dp"
android:maxResizeHeight="110dp">
</appwidget-provider>
Zastosowanie układów elastycznych
Jeśli układ musi się zmieniać w zależności od rozmiaru widżetu, zalecamy tworząc mały zestaw układów, z których każdy może mieć różne rozmiary. Jeśli nie jest możliwe, inną opcją jest określenie układów na podstawie dokładnie tego widżetu rozmiaru w czasie działania, jak opisano na tej stronie.
Ta funkcja zapewnia płynniejsze skalowanie i ogólnie lepszą skuteczność systemu. zdrowia, ponieważ system nie musi za każdym razem wybudzać aplikacji pojawi się widżet w innym rozmiarze.
Poniższy przykładowy kod pokazuje, jak udostępnić listę układów.
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); }
Załóżmy, że widżet ma te atrybuty:
<appwidget-provider
android:minResizeWidth="160dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="250dp"
android:maxResizeHeight="200dp">
</appwidget-provider>
Fragment kodu oznacza, że:
- Format
smallView
(obsługa od 160 dp (minResizeWidth
) × 110 dp) (minResizeHeight
) do 160 dp × 199 dp (następny punkt odcięcia – 1 dp). tallView
obsługuje parametry od 160 dp × 200 do 214 dp (następny punkt odcięcia – 1) × 200 dpwideView
obsługuje wymiary od 215 dp × 110 dp (minResizeHeight
) do 250 dp (maxResizeWidth
) × 200dp (maxResizeHeight
).
Twój widżet musi obsługiwać zakres rozmiarów od minResizeWidth
×
minResizeHeight
do maxResizeWidth
× maxResizeHeight
. W tym zakresie
możesz wybrać punkt ostateczny,
od którego chcesz zmienić układ.
![Przykład układu elastycznego](https://developer.android.com/static/images/appwidgets/size-range.gif?authuser=9&hl=pl)
Wybierz dokładny układ
Jeśli mały zestaw układów elastycznych nie jest dostępny, możesz zamiast tego przygotować różne układy dostosowane do rozmiarów, w których wyświetla się widżet. To jest zwykle dwóch rozmiarów dla telefonów (tryb pionowy i poziomy) i 4 rozmiary dla urządzeń składanych.
Aby wdrożyć to rozwiązanie, aplikacja musi wykonać te czynności:
Przeładuj
AppWidgetProvider.onAppWidgetOptionsChanged()
, która jest wywoływana, gdy zmienia się zbiór rozmiarów.Zadzwoń pod numer
AppWidgetManager.getAppWidgetOptions()
. , który zwracaBundle
zawierający rozmiary.Uzyskaj dostęp do klucza
AppWidgetManager.OPTION_APPWIDGET_SIZES
z systemuBundle
.
Ten przykładowy kod pokazuje, jak określić dokładne układy.
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) { }
Określanie rozmiaru widżetu
Każdy widżet musi definiować targetCellWidth
i targetCellHeight
dla urządzeń
z Androidem 12 lub nowszym albo z systemem minWidth
i minHeight
w przypadku wszystkich
wersji Androida (oznaczające minimalną ilość wykorzystywanego miejsca)
domyślnie. Jednak gdy użytkownicy dodają widżet do ekranu głównego,
zajmuje więcej miejsca niż określona przez Ciebie minimalna szerokość i wysokość.
Ekrany główne Androida oferują użytkownikom siatkę dostępnych miejsc,
umieszczanie widżetów i ikon. Ta siatka może się różnić w zależności od urządzenia. na przykład wiele
telefony komórkowe oferują siatkę o wymiarach 5 x 4, a tablety również mogą być wyświetlane w większej sieci. Gdy widżet
po dodaniu, rozciąga się, aby zająć minimalną liczbę komórek,
w poziomie i w pionie, wymagane do spełnienia ograniczeń
targetCellWidth
i targetCellHeight
na urządzeniach z uruchomionymi
Android 12 lub nowszy albo ograniczenia minWidth
i minHeight
są włączone
urządzeń z Androidem 11 (poziom interfejsu API 30) lub niższym.
szerokość i wysokość komórki oraz rozmiar zastosowanych automatycznych marginesów; mogą się różnić w zależności od urządzenia. Użyj tej tabeli, aby w przybliżeniu oszacować widżetu w typowym telefonie z siatką 5x4, biorąc pod uwagę liczba zajętych komórek siatki, które chcesz uwzględnić:
Liczba komórek (szerokość x wysokość) | Dostępny rozmiar w trybie pionowym (dp) | Dostępny rozmiar w trybie poziomym (dp) |
---|---|---|
1 × 1 | 57x102dp | 127x51dp |
2 × 1 | 130x102dp | 269x51dp |
3 × 1 | 203x102dp | 412x51dp |
10 × 15 cm | 276x102dp | 554x51dp |
13 × 18 cm | 349x102dp | 697x51dp |
13 × 28 cm | 349x220dp | 697x117dp |
13 × 15 cm | 349x337dp | 697x184dp |
13 × 15 cm | 349x455dp | 697x250dp |
… | ... | … |
N × M | (73 n – 16) x (118 m – 16) | (142 n – 15) x (66 m–15) |
Używaj rozmiarów komórek w trybie pionowym, aby przekazywać informacje dla wartości
atrybuty minWidth
, minResizeWidth
i maxResizeWidth
. Podobnie
użyj rozmiarów komórek w trybie poziomym, aby określić podane wartości
dla atrybutów minHeight
, minResizeHeight
i maxResizeHeight
.
Dzieje się tak, ponieważ w trybie pionowym szerokość komórki jest zwykle mniejsza. niż w trybie poziomym. Podobnie jest w przypadku komórki o wysokości w trybie poziomym jest mniejszy niż w trybie pionowym.
Jeśli na przykład chcesz zmniejszyć szerokość widżetu do jednej komórki
Google Pixel 4, ustaw minResizeWidth
na maksymalnie 56 dp
aby wartość atrybutu minResizeWidth
była mniejsza
niż 57 dp – bo komórka ma szerokość co najmniej 57 dp w orientacji pionowej.
Jeśli chcesz, by wysokość widżetu można było zmieniać w jednej komórce
na tym samym urządzeniu, ustaw minResizeHeight
na maksymalnie 50 dp,
wartość atrybutu minResizeHeight
jest mniejsza niż
51 dp – ponieważ jedna komórka ma wysokość co najmniej 51 dp w trybie poziomym.
Rozmiar każdego widżetu można zmienić w
minResizeWidth
/minResizeHeight
i maxResizeWidth
/maxResizeHeight
co oznacza, że musi dopasować się do dowolnego rozmiaru pomiędzy nimi.
Aby na przykład ustawić domyślny rozmiar widżetu w miejscu docelowym, możesz ustaw te atrybuty:
<appwidget-provider
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
Oznacza to, że domyślny rozmiar widżetu to 3 x 2 komórki, zgodnie z
Atrybuty targetCellWidth
i targetCellHeight
(lub 180 × 110 dp),
określone przez minWidth
i minHeight
dla urządzeń z
Android 11 lub starszy. W tym drugim przypadku rozmiar w komórkach
różnią się w zależności od urządzenia.
Aby ustawić obsługiwane zakresy rozmiarów widżetu, możesz ustawić następujące opcje: atrybuty:
<appwidget-provider
android:minResizeWidth="180dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="530dp"
android:maxResizeHeight="450dp">
</appwidget-provider>
Zgodnie z poprzednimi atrybutami szerokość widżetu wynosi można zmieniać od 180 do 530 dp, a wysokość można zmieniać w zakresie od 110 do 450 dp. Rozmiar widżetu można zmienić z komórek 3 x 2 na 5 x 2, pod warunkiem że: występują warunki:
- Urządzenie ma siatkę 5 x 4.
- Mapowanie liczby komórek na dostępny rozmiar w dps jest zgodna z tabelą przedstawiającą szacowaną wartość minimalną na tej stronie.
- Widżet dostosowuje się do tego zakresu rozmiarów.
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);
Załóżmy, że widżet korzysta z układów elastycznych zdefiniowanych w poprzednim kroku
fragmentów kodu. Oznacza to, że układ określony jako
Wartość R.layout.widget_weather_forecast_small
została użyta w zakresie 180 dp (minResizeWidth
) x
110 dp (minResizeHeight
) do 269 x 279 dp (następne punkty odcięcia – 1). Podobnie
Zasób R.layout.widget_weather_forecast_medium
jest używany od 270 x 110 dp do 270 x 279 dp,
a R.layout.widget_weather_forecast_large
jest używany od 270 x 280 dp do
530dp (maxResizeWidth
) x 450dp (maxResizeHeight
).
Gdy użytkownik zmienia rozmiar widżetu, jego wygląd dostosowuje się do rozmiaru komórki zgodnie z poniższymi przykładami.
![Przykładowy widżet pogody w najmniejszym rozmiarze siatki 3 x 2. Interfejs przedstawiający
nazwa lokalizacji (Tokio), temperatura (14°) oraz symbol wskazujący
częściowe zachmurzenie.](https://developer.android.com/static/images/appwidgets/weather-size-3x2.png?authuser=9&hl=pl)
R.layout.widget_weather_forecast_small
.![Przykładowy widżet pogody w rozmiarze 10 x 15 cm rozmiaru. Zmiana rozmiaru widżetu
w ten sposób bazuje na całym interfejsie użytkownika poprzedniego rozmiaru widżetu,
i dodaje etykietę „Przeważnie zachmurzone” i prognoza temperatur od
16:00–19:00.](https://developer.android.com/static/images/appwidgets/weather-size-4x2.png?authuser=9&hl=pl)
R.layout.widget_weather_forecast_medium
.![Przykładowy widżet pogody w rozmiarze 5 x 2 „średni” rozmiaru. Zmiana rozmiaru widżetu
w ten sposób interfejs wygląda tak samo jak poprzedni rozmiar, ale
rozciąga się o jedną komórkę, aby zająć więcej miejsca w poziomie.](https://developer.android.com/static/images/appwidgets/weather-size-5x2.png?authuser=9&hl=pl)
R.layout.widget_weather_forecast_medium
.![Przykładowy widżet pogody w dużym rozmiarze 5 x 3 rozmiaru. Zmiana rozmiaru widżetu
w ten sposób bazuje na całym interfejsie użytkownika
z poprzednich rozmiarów widżetów,
i dodaje do widżetu widok z prognozą pogody
we wtorek i w środę. Symbole wskazujące, że pogoda słoneczna lub deszczowa
oraz wysokie i niskie temperatury każdego dnia.](https://developer.android.com/static/images/appwidgets/weather-size-5x3.png?authuser=9&hl=pl)
R.layout.widget_weather_forecast_large
.![Przykładowy widżet pogody w dużym rozmiarze 5 x 4 rozmiaru. Zmiana rozmiaru widżetu
w ten sposób bazuje na całym interfejsie użytkownika
z poprzednich rozmiarów widżetów,
z dodanym „czwartek” i „piątek” (oraz odpowiadające im symbole)
wskazujący rodzaj pogody oraz temperaturę minimalną i maksymalną
).](https://developer.android.com/static/images/appwidgets/weather-size-5x4.png?authuser=9&hl=pl)
R.layout.widget_weather_forecast_large
.