Widżety aplikacji to miniatury aplikacji, które możesz umieszczać w innych aplikacjach (np. na ekranie głównym) i regularnie aktualizować. W interfejsie te widoki są nazywane widżetami. Możesz opublikować jeden z nich za pomocą dostawcy widżetów aplikacji (czyli dostawcy widżetów). Składnik aplikacji, który zawiera inne widżety, nazywa się hostem widżetu aplikacji (lub hostem widżetu). Ilustracja 1 przedstawia widżet z przykładową muzyką:
Z tego dokumentu dowiesz się, jak opublikować widżet za pomocą dostawcy widżetów. Szczegółowe informacje o tworzeniu własnych AppWidgetHost
do hostowania widżetów aplikacji znajdziesz w artykule Tworzenie hosta widżetów.
Informacje o projektowaniu widżetów znajdziesz w artykule Przegląd widżetów aplikacji.
Komponenty widżetu
Aby utworzyć widżet, potrzebujesz następujących podstawowych komponentów:
AppWidgetProviderInfo
obiekt- Opisuje metadane widżetu, takie jak układ, częstotliwość aktualizacji i klasa
AppWidgetProvider
. WartośćAppWidgetProviderInfo
jest zdefiniowana w pliku XML zgodnie z opisem w tym dokumencie. AppWidgetProvider
zajęcia- Określa podstawowe metody, które umożliwiają programowe tworzenie interfejsu z widżetem. Dzięki niemu otrzymujesz powiadomienia, gdy widżet zostanie zaktualizowany, włączony, wyłączony lub usunięty. Zadeklaruj
AppWidgetProvider
w pliku manifestu, a następnie wdróż go zgodnie z opisem w tym dokumencie. - Wyświetlanie układu
- Określa początkowy układ widżetu. Układ jest zdefiniowany w formacie XML, zgodnie z opisem w tym dokumencie.
Na rysunku 2 widać, jak te komponenty pasują do ogólnego przepływu danych w przypadku widżetów aplikacji.
Jeśli widżet wymaga konfiguracji przez użytkownika, zaimplementuj odpowiednią aktywność. Ta aktywność umożliwia użytkownikom modyfikowanie ustawień widżetów, np. strefy czasowej w widżecie zegara.
- Począwszy od Androida 12 (poziom interfejsu API 31) możesz podać 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.
- W Androidzie 11 (poziom interfejsu API 30) lub starszym ta aktywność jest uruchamiana za każdym razem, gdy użytkownik doda widżet do ekranu głównego.
Polecamy też te usprawnienia: elastyczne układy widżetów, różne ulepszenia, zaawansowane widżety, widżety kolekcji i tworzenie hosta widżetów.
Zadeklaruj plik XML AppWidgetProviderInfo
Obiekt AppWidgetProviderInfo
definiuje najważniejsze właściwości widżetu.
Zdefiniuj obiekt AppWidgetProviderInfo
w pliku zasobu XML, używając pojedynczego elementu <appwidget-provider>
, i zapisz go w folderze res/xml/
projektu.
Przykład:
<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 widgeta
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 pozwala na umieszczanie widżetów o rozmiarze będącym wielokrotnością liczby całkowitej komórek siatki – na przykład 2 komórki w poziomie i 3 komórki w pionie.
Atrybuty rozmiaru widżetu umożliwiają określenie domyślnego rozmiaru widżetu oraz podanie dolnego i górnego limitu rozmiaru. W tym kontekście domyślny rozmiar widżetu to rozmiar, który widżet ma, gdy jest po raz pierwszy dodawany do ekranu głównego.
W tej tabeli opisano atrybuty <appwidget-provider>
dotyczące rozmiaru widgeta:
Atrybuty i opis | |
---|---|
targetCellWidth i
targetCellHeight (Android 12),
minWidth i minHeight |
targetCellWidth i targetCellHeight oraz minWidth i minHeight – aby aplikacja mogła ponownie używać minWidth i minHeight , jeśli urządzenie użytkownika nie obsługuje targetCellWidth i targetCellHeight . Jeśli atrybuty targetCellWidth i targetCellHeight są obsługiwane, mają pierwszeństwo przed atrybutami minWidth i minHeight .
|
minResizeWidth i minResizeHeight |
Określ bezwzględny minimalny rozmiar widżetu. Te wartości określają rozmiar, przy którym widżet jest niewyraźny lub nieużyteczny. Korzystanie z tych atrybutów umożliwia użytkownikowi zmianę rozmiaru widżetu na mniejszy niż domyślny. Atrybut minResizeWidth jest ignorowany, jeśli jest większy niż minWidth lub jeśli nie jest włączone poziome dostosowywanie rozmiaru. Zobacz resizeMode . Podobnie atrybut minResizeHeight jest ignorowany, jeśli jest większy niż minHeight lub jeśli nie jest włączone skalowanie pionowe. |
maxResizeWidth i maxResizeHeight |
Określ zalecany maksymalny rozmiar widżetu. Jeśli wartości nie są wielokrotnością wymiarów komórki z siatką, są zaokrąglane w górę do najbliższego rozmiaru komórki. Atrybut maxResizeWidth jest ignorowany, jeśli jest mniejszy niż minWidth lub jeśli nie jest włączone poziome dostosowywanie rozmiaru. Zobacz resizeMode . Podobnie atrybut maxResizeHeight jest ignorowany, jeśli jest większy niż minHeight lub jeśli nie jest włączone skalowanie pionowe.
Wprowadzone w Androidzie 12. |
resizeMode |
Określa reguły, według których można zmieniać rozmiar widżetu. Za pomocą tego atrybutu możesz zmienić rozmiar widżetów na ekranie głównym w układzie poziomym, pionowym lub na obu osiach. Użytkownicy mogą nacisnąć i przytrzymać widżet, aby wyświetlić uchwyty do zmiany rozmiaru, a potem przeciągnąć uchwyty poziome lub pionowe, aby zmienić jego rozmiar na siatce układu. Wartości atrybutu resizeMode to horizontal , vertical i none . Aby zadeklarować widżet z możliwością zmiany rozmiaru w poziomie i w pionie, użyj właściwości horizontal|vertical . |
Przykład
Aby zilustrować, jak atrybuty z poprzedniej tabeli wpływają na rozmiar widżetu, załóżmy następujące specyfikacje:
- Komórka siatki ma 30 dp szerokości i 50 dp wysokości.
- Oto specyfikacja 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 widgetu.
Domyślny rozmiar widżetu to 2 x 2. Rozmiar widżetu można zmienić na 2 x 1 lub 4 x 3.
Android 11 i starsze wersje:
Użyj atrybutów minWidth
i minHeight
, aby obliczyć domyślny rozmiar widgeta.
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 zmienić na 2 x 1 lub na pełny ekran.
Dodatkowe atrybuty widżetu
W tej tabeli opisano atrybuty <appwidget-provider>
dotyczące właściwości innych niż rozmiary widgetów.
Atrybuty i opis | |
---|---|
updatePeriodMillis |
Określa, jak często platforma widżetu prosi o aktualizację AppWidgetProvider , wywołując metodę wywołania zwrotnego onUpdate() . Nie ma gwarancji, że rzeczywista aktualizacja nastąpi dokładnie w odpowiednim czasie. Zalecamy przeprowadzanie aktualizacji jak najrzadsze – nie częściej niż raz na godzinę – w celu oszczędzania baterii.
Pełną listę uwag na temat wyboru odpowiedniego okresu aktualizacji znajdziesz w artykule Optymalizacje pod kątem aktualizowania zawartości widżetu. |
initialLayout |
Odwołuje się do zasobu układu, który definiuje układ widżetu. |
configure |
Określa aktywność, która uruchamia się, gdy użytkownik doda widżet, umożliwiając mu skonfigurowanie jego właściwości. Zapoznaj się z artykułem Umożliwienie użytkownikom konfigurowania widżetów. Od Androida 12 aplikacja może pominąć początkową konfigurację. Więcej informacji znajdziesz w sekcji Używanie domyślnej konfiguracji widżetu. |
description |
Określa opis, który będzie wyświetlany w selektorze widżetów. Wprowadzone w Androidzie 12. |
previewLayout (Android 12)
i previewImage (Android 11 i starsze) |
previewImage i previewLayout , aby aplikacja mogła użyć atrybutu previewImage , jeśli urządzenie użytkownika nie obsługuje atrybutu 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 zaawansowany przez hosta widżetu. |
widgetCategory |
Określa, czy widżet może być wyświetlany na ekranie głównym (home_screen ), ekranie blokady (keyguard ) czy na obu tych ekranach. W przypadku Androida 5.0 lub nowszego prawidłowa jest tylko home_screen .
|
widgetFeatures |
Deklaruje funkcje obsługiwane przez widżet. Jeśli np. chcesz, aby widget używał domyślnej konfiguracji po dodaniu przez użytkownika, określ flagi configuration_optional i reconfigurable . Dzięki temu nie trzeba uruchamiać czynności konfiguracyjnej po dodaniu widżetu przez użytkownika. Użytkownik może później ponownie skonfigurować widget. |
Użyj klasy AppWidgetProvider do obsługi komunikatów widżetów
Klasa AppWidgetProvider
obsługuje transmisje danych z widżetów i aktualizuje widżet w odpowiedzi na zdarzenia cyklu życia widżetu. W sekcjach poniżej opisujemy, jak zadeklarować AppWidgetProvider
w pliku manifestu, a potem go wdrożyć.
Zadeklarowanie widżetu w pliku manifestu
Najpierw zadeklaruj klasę AppWidgetProvider
w pliku AndroidManifest.xml
aplikacji, jak 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 AppWidgetProvider
używany przez widżet. Komponentu nie można eksportować, chyba że do rozgłaszania AppWidgetProvider
trzeba przesłać oddzielny proces, co zwykle nie jest konieczne.
Element <intent-filter>
musi zawierać element <action>
z atrybutem android:name
. Ten atrybut określa, że AppWidgetProvider
akceptuje
ACTION_APPWIDGET_UPDATE
transmisję. To jedyna transmisja, którą musisz wyraźnie zadeklarować. AppWidgetManager
automatycznie wysyła wszystkie inne transmisje widżetu do AppWidgetProvider
w razie potrzeby.
Element <meta-data>
określa zasób AppWidgetProviderInfo
i wymaga podania tych atrybutów:
android:name
: określa nazwę metadanych. Użyj atrybutuandroid.appwidget.provider
, aby oznaczyć dane jako opisAppWidgetProviderInfo
.android:resource
: określa lokalizację zasobuAppWidgetProviderInfo
.
Implementacja klasy AppWidgetProvider
Klasa AppWidgetProvider
rozszerza klasę BroadcastReceiver
jako klasa ułatwiająca obsługę transmisji widżetów. Otrzymuje tylko transmisje zdarzeń, które są istotne dla widżetu, np. gdy widżet jest aktualizowany, usuwany, włączany lub wyłączany. W przypadku wystąpienia takich transmisji wywoływane są następujące metody AppWidgetProvider
:
onUpdate()
- Wywołuje się to do aktualizowania widżetu w odstępach czasowych określonych przez atrybut
updatePeriodMillis
wAppWidgetProviderInfo
. 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 dodaje widżet, aby wykonać niezbędną konfigurację, np. zdefiniować przetwarzacze zdarzeń dla obiektów
View
lub uruchomić zadania wczytywania danych do wyświetlenia w widżecie. Jeśli jednak deklarujesz aktywność konfiguracji bez flagiconfiguration_optional
, ta metoda nie zostanie wywołana, gdy użytkownik doda widżet, ale będzie wywoływana podczas kolejnych aktualizacji. Po zakończeniu konfiguracji pierwszą aktualizację musi wykonać aktywność konfiguracji. Więcej informacji znajdziesz w artykule Włączanie użytkownikom możliwości konfigurowania widżetów aplikacji. - Najważniejsze wywołanie zwrotne to
onUpdate()
. Więcej informacji znajdziesz na stronie Obsługa zdarzeń za pomocą klasyonUpdate()
. onAppWidgetOptionsChanged()
Ta funkcja jest wywoływana przy pierwszym umieszczaniu widżetu i przy każdorazowej zmianie jego rozmiaru. Za pomocą tego wywołania zwrotnego możesz wyświetlać lub ukrywać treści na podstawie zakresów rozmiarów widżetu. Aby uzyskać zakresy rozmiarów (a od Androida 12 – listę możliwych rozmiarów, które może przyjąć instancja widżetu), wywołaj funkcję
getAppWidgetOptions()
, która zwraca obiektBundle
zawierający:OPTION_APPWIDGET_MIN_WIDTH
: zawiera dolny limit szerokości (w pikselach) instancji widżetu.OPTION_APPWIDGET_MIN_HEIGHT
: zawiera dolny limit wysokości (w pikselach) instancji widżetu.OPTION_APPWIDGET_MAX_WIDTH
: zawiera górną granicę szerokości (w jednostkach dp) instancji widżetu.OPTION_APPWIDGET_MAX_HEIGHT
: zawiera górną granicę wysokości (w jednostkach dp) instancji widżetu.OPTION_APPWIDGET_SIZES
: zawiera listę możliwych rozmiarów (List<SizeF>
) w jednostkach dp, które może przyjąć instancja widżetu. Wprowadzone w Androidzie 12.
onDeleted(Context, int[])
Jest ona wywoływana za każdym razem, gdy widżet zostanie usunięty z hosta widżetów.
onEnabled(Context)
Jest on wywoływany, gdy instancja widżetu jest tworzona po raz pierwszy. Jeśli na przykład użytkownik doda 2 wystąpienia widżetu, metoda ta zostanie wywołana tylko raz. Jeśli chcesz otworzyć nową bazę danych lub przeprowadzić inną konfigurację, która musi zostać wykonana tylko raz w przypadku wszystkich wystąpień widżetu, możesz to zrobić w tym miejscu.
onDisabled(Context)
Ta metoda jest wywoływana, gdy ostatnia instancja widżetu zostanie usunięta z hosta widżetu. Tutaj możesz uporządkować wszystkie działania wykonane w
onEnabled(Context)
, na przykład usunąć tymczasową bazę danych.onReceive(Context, Intent)
Jest on wywoływany w przypadku 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żetów i wywołuje poprzednie metody odpowiednio.
Implementację klasy AppWidgetProvider
musisz zadeklarować jako odbiornik transmisji za pomocą elementu <receiver>
w komponencie AndroidManifest
. Więcej informacji znajdziesz na stronie Deklarowanie widżetu w pliku manifestu.
Obsługa zdarzeń za pomocą klasy onUpdate()
Najważniejsze wywołanie zwrotne AppWidgetProvider
to onUpdate()
, ponieważ jest ono wywoływane przy dodawaniu każdego widżetu do hosta, chyba że użyjesz działania konfiguracyjnego bez flagi configuration_optional
. Jeśli widżet akceptuje jakiekolwiek zdarzenia interakcji z użytkownikiem, zarejestruj moduły obsługi zdarzeń w tym wywołaniu zwrotnym. Jeśli widżet nie tworzy plików tymczasowych ani baz danych albo nie wykonuje innych zadań wymagających wyczyszczenia, jedyną metodą wywołania zwrotnego, jaką musisz zdefiniować, może być onUpdate()
.
Jeśli np. chcesz mieć widżet z przyciskiem, który po kliknięciu uruchamia aktywność 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 AppWidgetProvider
definiuje tylko metodę onUpdate()
, wykorzystując ją do utworzenia PendingIntent
, która uruchamia Activity
i dołącza ją do przycisku widżetu za pomocą setOnClickPendingIntent(int,
PendingIntent)
. Zawiera pętlę, która powoduje iterację każdego wpisu w usłudze appWidgetIds
, czyli tablicę identyfikatorów identyfikujących każdy widżet utworzony przez tego dostawcę. Jeśli użytkownik utworzy więcej niż 1 wystąpieni widżetu, wszystkie zostaną zaktualizowane jednocześnie. Jednak dla wszystkich wystąpień widżetu zarządzana jest tylko jedna updatePeriodMillis
. Jeśli na przykład harmonogram aktualizacji jest ustawiony co 2 godziny, a po godzinie od dodania pierwszego widgeta dodasz drugi, oba zostaną zaktualizowane zgodnie z harmonogramem pierwszego, a drugi okres aktualizacji zostanie zignorowany. Oba te raporty są aktualizowane co 2 godziny, a nie co godzinę.
Więcej informacji znajdziesz w próbnej klasie ExampleAppWidgetProvider.java
.
Odbieranie intencji transmisji widżetu
AppWidgetProvider
to klasa ułatwiająca. Jeśli chcesz bezpośrednio otrzymywać komunikaty z widżetu, możesz zaimplementować własny element BroadcastReceiver
lub zastąpić wywołanie zwrotne onReceive(Context,Intent)
. Oto intencje, na których musisz się skupić:
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ółowe informacje znajdziesz w wytycznych dotyczących projektowania.
Jeśli znasz schematy, utworzenie układu widżetu jest proste. Pamiętaj jednak, że układy widżetów są oparte na narzędziu RemoteViews
, który nie obsługuje wszystkich rodzajów układów lub widżetów. Nie możesz używać niestandardowych widoków ani podklas widoków obsługiwanych przez RemoteViews
.
RemoteViews
obsługuje też ViewStub
, czyli niewidoczny, zerowy View
, którego można użyć do leniwego napełniania zasobów układu w czasie działania.
Obsługa zachowania stanowego
Android 12 obsługuje stany za pomocą tych istniejących komponentów:
Widżet nadal nie ma stanu. 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));
Podaj 2 projekty: jeden kierowany na urządzenia z Androidem 12 lub nowszym w folderze res/layout-v31
, a drugi na poprzednią wersję Androida 11 lub starszą w domyślnym folderze res/layout
.
Stosuj zaokrąglone rogi.
Android 12 wprowadza te parametry systemu, które umożliwiają ustawienie 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. Jest to dokładnie o 8 dp mniejsze od promienia tła, aby zapewnić odpowiednie dopasowanie przy korzystaniu z dopełnienia 8 dp.
Ten przykład pokazuje widżet, który używa wartości system_app_widget_background_radius
dla rogu widżetu i system_app_widget_inner_radius
dla widoków wewnątrz widżetu.
1 Róg widżetu.
2 Rzut oka na widok wewnątrz widżetu.
Ważne uwagi dotyczące zaokrąglonych narożników
- Programy uruchamiające i producenci innych urządzeń mogą zastąpić parametr
system_app_widget_background_radius
mniejszy niż 28 dp. Parametrsystem_app_widget_inner_radius
jest zawsze mniejszy o 8 pikseli od wartości parametrusystem_app_widget_background_radius
. - Jeśli widżet nie używa
@android:id/background
lub ma zdefiniowany tło, które nakłada treść na podstawie obrysu (android:clipToOutline
ma wartośćtrue
), program uruchamiający automatycznie rozpoznaje tło i przycina widżet za pomocą prostokąta z zaokrąglonymi rogami do 16 dp. Zapoznaj się z artykułem Sprawdzanie zgodności widżetu z Androidem 12.
Aby zapewnić zgodność widżetu z wcześniejszymi wersjami systemu Android, zalecamy zdefiniowanie atrybutów niestandardowych i użycie niestandardowego motywu, aby zastąpić je w Androidzie 12. Przykładowe pliki 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" />