Widżety to miniaturowe widoki aplikacji, które możesz umieścić w innych aplikacjach, np. na ekranie głównym, i otrzymywać okresowe aktualizacje. Widoki te w interfejsie są nazywane widżetami. Można je publikować, korzystając z dostawcy widżetu aplikacji (lub dostawcy widżetu). Komponent aplikacji, który zawiera inne widżety, jest nazywany hostem widżetów aplikacji (lub hostem widżetów). Rysunek 1 przedstawia przykładowy widżet muzyczny:
W tym dokumencie opisano sposób publikowania widżetu przy użyciu dostawcy widżetu. Szczegółowe informacje na temat tworzenia własnego AppWidgetHost
do hostowania widżetów aplikacji znajdziesz w artykule Tworzenie hosta widżetów.
Więcej informacji o projektowaniu widżetu znajdziesz w artykule Omówienie widżetów aplikacji.
Komponenty widżetów
Aby utworzyć widżet, potrzebujesz tych podstawowych komponentów:
AppWidgetProviderInfo
obiekt- Opisuje metadane widżetu, takie jak jego układ, częstotliwość aktualizacji i klasa
AppWidgetProvider
. ParametrAppWidgetProviderInfo
jest zdefiniowany w pliku XML zgodnie z opisem w tym dokumencie. AppWidgetProvider
zajęcia- Definiuje podstawowe metody umożliwiające programistyczny interfejs użytkownika widżeta. Dzięki temu będziesz otrzymywać komunikaty o aktualizacjach, włączeniu, wyłączeniu lub usunięciu widżetu. Zadeklarujesz właściwość
AppWidgetProvider
w pliku manifestu, a następnie zaimplementujesz ją zgodnie z opisem w tym dokumencie .
- Wyświetl układ
- Określa początkowy układ widżetu. Układ jest zdefiniowany w formacie XML zgodnie z opisem w tym dokumencie.
Rysunek 2 pokazuje, jak te komponenty wpisują się w ogólny proces przetwarzania widżetów aplikacji.
Jeśli Twój widżet wymaga konfiguracji użytkownika, wdróż aktywność związaną z konfiguracją widżetu aplikacji. Ta aktywność pozwala użytkownikom modyfikować ustawienia widżetu, na przykład strefę czasową widżetu zegara.
- Od Androida 12 (poziom interfejsu API 31) możesz określić konfigurację domyślną i umożliwić użytkownikom ponowne skonfigurowanie widżetu. Więcej informacji znajdziesz w artykułach Używanie domyślnej konfiguracji widżetu i Zezwalanie użytkownikom na zmianę konfiguracji umieszczonych widżetów.
- Na Androidzie 11 (poziom interfejsu API 30) i starszych ta aktywność jest uruchamiana za każdym razem, gdy użytkownik doda widżet do ekranu głównego.
Zalecamy też wprowadzenie tych ulepszeń: elastyczne układy widżetów, różne ulepszenia, zaawansowane widżety, widżety kolekcji oraz utworzenie hosta widżetów.
Deklarowanie pliku XML AppWidgetProviderInfo
Obiekt AppWidgetProviderInfo
definiuje podstawowe cechy widżetu.
Zdefiniuj obiekt AppWidgetProviderInfo
w pliku zasobów XML za pomocą pojedynczego elementu <appwidget-provider>
i zapisz go w folderze res/xml/
projektu.
Widać to w tym przykładzie:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:targetCellWidth="1"
android:targetCellHeight="1"
android:maxResizeWidth="250dp"
android:maxResizeHeight="120dp"
android:updatePeriodMillis="86400000"
android:description="@string/example_appwidget_description"
android:previewLayout="@layout/example_appwidget_preview"
android:initialLayout="@layout/example_loading_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>
Atrybuty rozmiaru widżetów
Domyślny ekran główny umieszcza widżety w oknie na podstawie siatki komórek o określonej wysokości i szerokości. Większość ekranów głównych zezwala widżetom na przyjmowanie tylko tych rozmiarów, które są wielokrotnościami liczb całkowitych komórek siatki, np. 2 komórki w poziomie i 3 komórki w pionie.
Atrybuty rozmiaru widżetu pozwalają określić domyślny rozmiar widżetu oraz określić dolne i górne granice rozmiaru widżetu. W tym kontekście domyślny rozmiar widżetu to jego rozmiar po dodaniu go do ekranu głównego.
W tabeli poniżej opisujemy atrybuty <appwidget-provider>
związane z rozmiarem widżetu:
Atrybuty i opis | |
---|---|
targetCellWidth i targetCellHeight (Android 12), minWidth i minHeight |
targetCellWidth i targetCellHeight oraz minWidth i minHeight – dzięki temu aplikacja będzie mogła wrócić do korzystania z minWidth i minHeight , jeśli urządzenie użytkownika nie obsługuje targetCellWidth i targetCellHeight . Jeśli są obsługiwane, atrybuty targetCellWidth i targetCellHeight mają pierwszeństwo przed atrybutami minWidth i minHeight .
|
minResizeWidth i minResizeHeight |
Określ absolutny minimalny rozmiar widżetu. Te wartości określają rozmiar, pod którym widżet jest nieczytelny lub z innego powodu bezużyteczny. Użycie tych atrybutów umożliwia użytkownikowi zmianę rozmiaru widżetu do rozmiaru mniejszego niż domyślny. Atrybut minResizeWidth jest ignorowany, jeśli ma wartość większą niż minWidth lub jeśli zmiana rozmiaru w poziomie nie jest włączona. Zobacz resizeMode . Podobnie atrybut minResizeHeight jest ignorowany, jeśli ma wartość większą niż minHeight lub jeśli zmiana rozmiaru w pionie nie jest włączona. |
maxResizeWidth i maxResizeHeight |
Określ zalecany maksymalny rozmiar widżetu. Jeśli wartości nie są wielokrotnością wymiarów komórki siatki, są zaokrąglane w górę do najbliższego rozmiaru komórki. Atrybut maxResizeWidth jest ignorowany, jeśli ma wartość mniejszą niż minWidth lub jeśli nie jest włączona zmiana rozmiaru w poziomie. Zobacz resizeMode . Podobnie atrybut maxResizeHeight jest ignorowany, jeśli ma wartość większą niż minHeight lub jeśli zmiana rozmiaru w pionie nie jest włączona.
Wprowadzona w Androidzie 12. |
resizeMode |
Określa reguły, według których można zmieniać rozmiar widżetu. Możesz użyć tego atrybutu, aby zmienić rozmiar widżetów ekranu głównego w poziomie, w pionie lub na obu osiach. Użytkownicy mogą kliknąć i przytrzymać widżet, aby wyświetlić jego uchwyty zmiany rozmiaru, a następnie przeciągnąć poziome lub pionowe uchwyty, aby zmienić jego rozmiar na siatce układu. Wartości atrybutu resizeMode to horizontal , vertical i none . Aby zadeklarować widżet jako widżet z możliwością zmiany rozmiaru w poziomie i w pionie, użyj właściwości horizontal|vertical . |
Przykład
Aby pokazać, jak atrybuty z poprzedniej tabeli wpływają na rozmiar widżetu, przyjmijmy te specyfikacje:
- Komórka siatki ma szerokość 30 dp i wysokość 50 dp.
- Podano następującą specyfikację atrybutu:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="80dp"
android:minHeight="80dp"
android:targetCellWidth="2"
android:targetCellHeight="2"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:maxResizeWidth="120dp"
android:maxResizeHeight="120dp"
android:resizeMode="horizontal|vertical" />
Od Androida 12:
Użyj atrybutów targetCellWidth
i targetCellHeight
jako domyślnego rozmiaru widżetu.
Domyślny rozmiar widżetu to 2 x 2. Rozmiar widżetu można zmniejszyć do 2 x 1 lub do 4 x 3.
Android 11 lub starszy:
Aby obliczyć domyślny rozmiar widżetu, użyj atrybutów minWidth
i minHeight
.
Domyślna szerokość = Math.ceil(80 / 30)
= 3
Domyślna wysokość = Math.ceil(80 / 50)
= 2
Domyślny rozmiar widżetu to 3 x 2. Rozmiar widżetu można zmniejszyć do 2 x 1 lub do pełnego ekranu.
Dodatkowe atrybuty widżetu
W tabeli poniżej opisujemy atrybuty <appwidget-provider>
odnoszące się do jakości innych niż rozmiar widżetu.
Atrybuty i opis | |
---|---|
updatePeriodMillis |
Określa, jak często platforma widżetu żąda aktualizacji z AppWidgetProvider , wywołując metodę wywołania zwrotnego onUpdate() . Przy użyciu tej wartości nie możemy zagwarantować, że aktualizacja nastąpi dokładnie na czas. W celu oszczędzania baterii zalecamy rzadkie aktualizowanie, czyli nie częściej niż raz na godzinę.
Pełną listę uwag na temat wyboru odpowiedniego okresu aktualizacji znajdziesz w artykule Optymalizacje dotyczące aktualizowania zawartości widżetów. |
initialLayout |
Wskazuje zasób układu, który określa układ widżetu. |
configure |
Definiuje działanie, które ma być uruchamiane, gdy użytkownik doda widżet, i może konfigurować jego właściwości. Więcej informacji znajdziesz w artykule Zezwalanie użytkownikom na konfigurowanie widżetów. Od Androida 12 aplikacja może pomijać wstępną konfigurację. Więcej informacji znajdziesz w sekcji Używanie domyślnej konfiguracji widżetu. |
description |
Określa opis selektora widżetów, które będzie wyświetlany w przypadku widżetu. Wprowadzona w Androidzie 12. |
previewLayout (Android 12)
i previewImage (Android 11 i starsze) |
previewImage , jak i previewLayout , aby aplikacja mogła wrócić do korzystania z previewImage , jeśli urządzenie użytkownika nie obsługuje previewLayout . Więcej informacji znajdziesz w artykule o zgodności wstecznej ze skalowalnymi podglądami widżetów.
|
autoAdvanceViewId |
Określa identyfikator widoku podrzędnego widżetu, który jest automatycznie przesuwany przez host widżetu. |
widgetCategory |
Określa, czy widżet może być wyświetlany na ekranie głównym (home_screen ), na ekranie blokady (keyguard ) lub w obu tych miejscach. W przypadku Androida 5.0 lub nowszego prawidłowa jest tylko home_screen .
|
widgetFeatures |
Deklaruje funkcje obsługiwane przez widżet. Jeśli na przykład chcesz, aby widżet używał swojej domyślnej konfiguracji, gdy użytkownik go doda, podaj zarówno flagi configuration_optional , jak i reconfigurable . Pomija to uruchamianie działania konfiguracji po dodaniu widżetu przez użytkownika. Użytkownik może nadal ponownie skonfigurować widżet. |
Używanie klasy AppWidgetProvider do obsługi komunikatów widżetu
Klasa AppWidgetProvider
obsługuje transmisje widżetów i ich aktualizowanie w odpowiedzi na zdarzenia cyklu życia widżetu. W sekcjach poniżej dowiesz się, jak zadeklarować właściwość AppWidgetProvider
w pliku manifestu, a następnie ją wdrożyć.
Zadeklarowanie widżetu w pliku manifestu
Najpierw zadeklaruj klasę AppWidgetProvider
w pliku AndroidManifest.xml
aplikacji, jak pokazano w tym przykładzie:
<receiver android:name="ExampleAppWidgetProvider"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
Element <receiver>
wymaga atrybutu android:name
, który określa obiekt AppWidgetProvider
używany przez widżet. Komponentu nie można eksportować, chyba że do AppWidgetProvider
musi przesłać go osobny proces, co zwykle nie jest konieczne.
Element <intent-filter>
musi zawierać element <action>
z atrybutem android:name
. Ten atrybut określa, że AppWidgetProvider
akceptuje transmisję ACTION_APPWIDGET_UPDATE
. To jedyna transmisja, którą musisz wyraźnie zadeklarować. W razie potrzeby AppWidgetManager
automatycznie wysyła wszystkie pozostałe komunikaty widżetu do elementu AppWidgetProvider
.
Element <meta-data>
określa zasób AppWidgetProviderInfo
i wymaga tych atrybutów:
android:name
: określa nazwę metadanych. Użyjandroid.appwidget.provider
, aby określić dane jako deskryptorAppWidgetProviderInfo
.android:resource
: określa lokalizację zasobuAppWidgetProviderInfo
.
Implementowanie klasy AppWidgetProvider
Klasa AppWidgetProvider
stanowi rozwinięcie klasy BroadcastReceiver
jako klasy ułatwiającej obsługę transmisji widżetu. Otrzymuje tylko te transmisje zdarzeń, które są istotne dla widżetu, na przykład informacje o tym, kiedy widżet jest aktualizowany, usuwany, włączony lub wyłączony. Kiedy występują takie zdarzenia transmisji, wywoływane są te metody AppWidgetProvider
:
onUpdate()
- Jest ono wywoływane do aktualizowania widżetu w interwałach zdefiniowanych przez atrybut
updatePeriodMillis
w plikuAppWidgetProviderInfo
. Więcej informacji znajdziesz w tabeli z opisem dodatkowych atrybutów widżetów na tej stronie. - Ta metoda jest też wywoływana, gdy użytkownik doda widżet, więc wykonuje niezbędną konfigurację, np. definiowanie modułów obsługi zdarzeń dla obiektów
View
lub uruchamianie zadań wczytywania danych do wyświetlenia w widżecie. Jeśli jednak zadeklarujesz aktywność związaną z konfiguracją bez flagiconfiguration_optional
, ta metoda nie będzie wywoływana podczas dodawania widżetu, ale jest wywoływana przy kolejnych aktualizacjach. Obowiązkiem działania związanego z konfiguracją jest przeprowadzenie pierwszej aktualizacji po zakończeniu konfiguracji. Więcej informacji znajdziesz w artykule Zezwalanie użytkownikom na konfigurowanie widżetów aplikacji. - Najważniejsze wywołanie zwrotne to:
onUpdate()
. Więcej informacji znajdziesz w sekcji Obsługa zdarzeń za pomocą klasyonUpdate()
na tej stronie. onAppWidgetOptionsChanged()
Ta opcja jest wywoływana przy umieszczaniu widżetu po raz pierwszy i każdej zmianie jego rozmiaru. To wywołanie zwrotne służy do wyświetlania lub ukrywania treści zależnie od zakresów rozmiarów widżetu. Pobierz zakresy rozmiarów (począwszy od Androida 12, listę możliwych rozmiarów, jakie może przyjmować instancja widżetu), wywołując metodę
getAppWidgetOptions()
, która zwraca elementBundle
zawierający:OPTION_APPWIDGET_MIN_WIDTH
: zawiera dolną granicę szerokości instancji widżetu (w jednostkach dp).OPTION_APPWIDGET_MIN_HEIGHT
: zawiera dolną granicę wysokości instancji widżetu (w jednostkach dp).OPTION_APPWIDGET_MAX_WIDTH
: zawiera górną granicę szerokości instancji widżetu (w jednostkach dp).OPTION_APPWIDGET_MAX_HEIGHT
: zawiera górną granicę wysokości instancji widżetu (w jednostkach dp).OPTION_APPWIDGET_SIZES
: zawiera listę możliwych rozmiarów (List<SizeF>
) w jednostkach dp, które może przyjmować instancja widżetu. Wprowadzona w Androidzie 12.
onDeleted(Context, int[])
Ta funkcja jest wywoływana za każdym razem, gdy widżet zostanie usunięty z hosta widżetów.
onEnabled(Context)
Jest ono wywoływane podczas tworzenia instancji widżetu po raz pierwszy. Jeśli na przykład użytkownik doda 2 instancje Twojego widżetu, nazwa ta zostanie wywołana tylko za pierwszym razem. Jeśli musisz otworzyć nową bazę danych lub przeprowadzić inną konfigurację, którą trzeba wykonać tylko raz dla wszystkich instancji widżetów, jest to dobre miejsce.
onDisabled(Context)
Jest ono wywoływane, gdy ostatnie wystąpienie widżetu zostanie usunięte z hosta widżetu. W tym miejscu usuwasz wszystkie swoje zadania w
onEnabled(Context)
, na przykład usuwasz tymczasową bazę danych.onReceive(Context, Intent)
Jest ono wywoływane dla każdej transmisji i przed każdą z poprzednich metod wywołania zwrotnego. Zwykle nie musisz implementować tej metody, ponieważ domyślna implementacja
AppWidgetProvider
filtruje wszystkie komunikaty widżetu i w razie potrzeby wywołuje poprzednie metody.
Musisz zadeklarować implementację klasy AppWidgetProvider
jako odbiornik, używając elementu <receiver>
w obiekcie AndroidManifest
. Więcej informacji znajdziesz w sekcji Deklarowanie widżetu w pliku manifestu na tej stronie.
Obsługa zdarzeń za pomocą klasy onUpdate()
Najważniejszym wywołaniem zwrotnym AppWidgetProvider
jest onUpdate()
, ponieważ jest ono wywoływane po dodaniu każdego widżetu do hosta, chyba że używasz działania konfiguracyjnego bez flagi configuration_optional
. Jeśli Twój widżet akceptuje dowolne zdarzenia interakcji użytkownika, zarejestruj moduły obsługi zdarzeń w tym wywołaniu zwrotnym. Jeśli Twój widżet nie tworzy plików tymczasowych ani baz danych ani nie wykonuje innych czynności wymagających czyszczenia, onUpdate()
może być jedyną metodą wywołania zwrotnego, którą musisz zdefiniować.
Jeśli na przykład chcesz widżet z przyciskiem uruchamiającym działanie po kliknięciu, możesz użyć tej implementacji AppWidgetProvider
:
Kotlin
class ExampleAppWidgetProvider : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // Perform this loop procedure for each widget that belongs to this // provider. appWidgetIds.forEach { appWidgetId -> // Create an Intent to launch ExampleActivity. val pendingIntent: PendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ Intent(context, ExampleActivity::class.java), /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // Get the layout for the widget and attach an onClick listener to // the button. val views: RemoteViews = RemoteViews( context.packageName, R.layout.appwidget_provider_layout ).apply { setOnClickPendingIntent(R.id.button, pendingIntent) } // Tell the AppWidgetManager to perform an update on the current // widget. appWidgetManager.updateAppWidget(appWidgetId, views) } } }
Java
public class ExampleAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // Perform this loop procedure for each widget that belongs to this // provider. for (int i=0; i < appWidgetIds.length; i++) { int appWidgetId = appWidgetIds[i]; // Create an Intent to launch ExampleActivity Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( /* context = */ context, /* requestCode = */ 0, /* intent = */ intent, /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE ); // Get the layout for the widget and attach an onClick listener to // the button. RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app // widget. appWidgetManager.updateAppWidget(appWidgetId, views); } } }
Ten element AppWidgetProvider
definiuje tylko metodę onUpdate()
przy użyciu jej do tworzenia PendingIntent
, który uruchamia element Activity
i dołącza go do przycisku widżetu za pomocą setOnClickPendingIntent(int,
PendingIntent)
. Zawiera pętlę, która powtarza się po każdym wpisie w appWidgetIds
. Jest to tablica identyfikatorów identyfikujących każdy widżet utworzony przez tego dostawcę. Jeśli użytkownik utworzy więcej niż jedną instancję widżetu, będą one aktualizowane jednocześnie. Dla wszystkich instancji widżetu jest jednak zarządzany tylko 1 harmonogram updatePeriodMillis
. Jeśli na przykład harmonogram aktualizacji jest ustawiony na co 2 godziny, a drugie wystąpienie widżetu zostanie dodane po godzinie od pierwszego, oba zostaną zaktualizowane w okresie zdefiniowanym przez pierwszy, a drugi okres aktualizacji zostanie zignorowany. Obie są aktualizowane co 2 godziny, a nie co godzinę.
Więcej informacji znajdziesz w przykładowej klasie ExampleAppWidgetProvider.java
.
Odbieranie intencji transmisji widżetu
AppWidgetProvider
to klasa praktyczna. Jeśli chcesz bezpośrednio otrzymywać komunikaty z widżetu, możesz wdrożyć własne źródło BroadcastReceiver
lub zastąpić wywołanie zwrotne onReceive(Context,Intent)
. Intencje, na których Ci zależy, to:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
Tworzenie układu widżetu
Musisz zdefiniować początkowy układ widżetu w formacie XML i zapisać go w katalogu res/layout/
projektu. Szczegóły znajdziesz we wskazówkach dotyczących projektowania.
Tworzenie układu widżetu jest proste, jeśli znasz się na układach. Pamiętaj jednak, że układy widżetów bazują na usłudze RemoteViews
, która nie obsługuje wszystkich rodzajów układów i widżetów widoku. Nie możesz używać niestandardowych widoków ani podklas widoków obsługiwanych przez RemoteViews
.
RemoteViews
obsługuje też ViewStub
– niewidoczny obiekt View
o zerowym rozmiarze, którego można używać do leniwego powiększania zasobów układu w czasie działania.
Obsługa zachowań stanowych
Android 12 dodaje obsługę zachowania stanowego przy użyciu tych istniejących komponentów:
Widżet nadal jest bezstanowy. Aplikacja musi przechowywać stan i rejestrować zdarzenia zmiany stanu.
Poniższy przykładowy kod pokazuje, jak wdrożyć te komponenty.
Kotlin
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true) // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2) // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent) )
Java
// Check the view. remoteView.setCompoundButtonChecked(R.id.my_checkbox, true); // Check a radio group. remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2); // Listen for check changes. The intent has an extra with the key // EXTRA_CHECKED that specifies the current checked state of the view. remoteView.setOnCheckedChangeResponse( R.id.my_checkbox, RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));
Udostępnij 2 układy: jeden na urządzenia z Androidem 12 lub nowszym w res/layout-v31
, a drugi na Androida 11 lub starszego w domyślnym folderze res/layout
.
Stosowanie zaokrąglonych rogów
Android 12 wprowadza te parametry systemowe, aby ustawić promień zaokrąglonych rogów widżetu:
system_app_widget_background_radius
: promień narożnika tła widżetu, który nigdy nie przekracza 28 dp.system_app_widget_inner_radius
: promień narożnika dowolnego widoku w widżecie. To dokładnie 8 dp mniej niż promień tła, co pozwala uzyskać lepsze wyrównanie przy dopełnieniu o 8 dp.
Poniższy przykład przedstawia widżet, w którym użyto system_app_widget_background_radius
jako narożnika widżetu oraz system_app_widget_inner_radius
do wyświetlania jego widoków.
1 Króg widżetu.
2 Króg widoku w widżecie.
Ważne informacje na temat zaokrąglonych rogów
- Zewnętrzne Menu z aplikacjami i producenci urządzeń mogą zastąpić parametr
system_app_widget_background_radius
tak, by jego wartość była mniejsza niż 28 dp. Parametrsystem_app_widget_inner_radius
jest zawsze o 8 dp mniejszy niż wartość parametrusystem_app_widget_background_radius
. - Jeśli Twój widżet nie używa
@android:id/background
ani nie zdefiniujesz tła, które przycina jego zawartość na podstawie obrysu (przy ustawieniuandroid:clipToOutline
ma wartośćtrue
), program uruchamiający automatycznie identyfikuje tło i przycina widżet za pomocą prostokąta z zaokrąglonymi narożnikami o maksymalnych 16 dp. Zobacz Sprawdzanie, czy widżet jest zgodny z Androidem 12.
Aby zapewnić zgodność widżetów z poprzednimi wersjami Androida, zalecamy zdefiniowanie atrybutów niestandardowych i zastosowanie motywu niestandardowego do zastąpienia ich w Androidzie 12, jak pokazano w tych przykładowych plikach XML:
/values/attrs.xml
<resources>
<attr name="backgroundRadius" format="dimension" />
</resources>
/values/styles.xml
<resources>
<style name="MyWidgetTheme">
<item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
</style>
</resources>
/values-31/styles.xml
<resources>
<style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
<item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
</style>
</resources>
/drawable/my_widget_background.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="?attr/backgroundRadius" />
...
</shape>
/layout/my_widget_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:background="@drawable/my_widget_background" />