Widget aplikasi adalah tampilan aplikasi mini yang dapat Anda sematkan di aplikasi lain—seperti layar utama—dan menerima update berkala. Tampilan ini disebut sebagai widget dalam antarmuka pengguna, dan Anda dapat memublikasikan satu dengan penyedia widget aplikasi (atau penyedia widget). Komponen aplikasi yang menampung widget lain disebut host widget aplikasi (atau host widget). Gambar 1 menampilkan contoh widget musik:

Dokumen ini menjelaskan cara memublikasikan widget menggunakan penyedia widget. Untuk
detail tentang cara membuat AppWidgetHost
Anda sendiri untuk
menghosting widget aplikasi, lihat Membangun host widget.
Untuk mengetahui informasi tentang cara mendesain widget, lihat Ringkasan widget aplikasi.
Komponen widget
Untuk membuat widget, Anda memerlukan komponen dasar berikut:
- Objek
AppWidgetProviderInfo
- Menjelaskan metadata untuk widget, seperti tata letak widget, frekuensi
update, dan class
AppWidgetProvider
.AppWidgetProviderInfo
ditentukan dalam XML, seperti yang dijelaskan dalam dokumen ini. - Class
AppWidgetProvider
- Menentukan metode dasar yang memungkinkan Anda berinteraksi secara terprogram dengan
widget. Melalui aplikasi ini, Anda menerima siaran saat widget diupdate,
diaktifkan, dinonaktifkan, atau dihapus. Anda mendeklarasikan
AppWidgetProvider
di manifest, lalu menerapkannya, seperti yang dijelaskan dalam dokumen ini. - Tata letak tampilan
- Menentukan tata letak awal untuk widget. Tata letak ditentukan dalam XML, seperti yang dijelaskan dalam dokumen ini.
Gambar 2 menunjukkan cara komponen ini sesuai dengan alur pemrosesan widget aplikasi secara keseluruhan.

Jika widget Anda memerlukan konfigurasi pengguna, terapkan aktivitas konfigurasi widget aplikasi. Aktivitas ini memungkinkan pengguna mengubah setelan widget—misalnya, zona waktu untuk widget jam.
- Mulai Android 12 (level API 31), Anda dapat memberikan konfigurasi default dan memungkinkan pengguna mengonfigurasi ulang widget nanti. Lihat Menggunakan konfigurasi default widget dan Memungkinkan pengguna mengonfigurasi ulang widget yang ditempatkan untuk mengetahui detail selengkapnya.
- Di Android 11 (level API 30) atau yang lebih rendah, aktivitas ini diluncurkan setiap kali pengguna menambahkan widget ke layar utama.
Kami juga merekomendasikan peningkatan berikut: tata letak widget yang fleksibel, peningkatan lain-lain, widget lanjutan, widget koleksi, dan membangun host widget.
Mendeklarasikan XML AppWidgetProviderInfo
Objek AppWidgetProviderInfo
menentukan kualitas penting widget.
Tentukan objek AppWidgetProviderInfo
dalam file resource XML menggunakan satu elemen
<appwidget-provider>
dan simpan ke folder res/xml/
project.
Hal ini ditunjukkan dalam contoh berikut:
<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>
Atribut ukuran widget
Layar utama default menentukan posisi widget dalam jendelanya berdasarkan petak sel yang memiliki tinggi dan lebar yang ditentukan. Sebagian besar layar utama hanya mengizinkan widget mengambil ukuran yang merupakan kelipatan bilangan bulat dari sel petak—misalnya, dua sel secara horizontal dan tiga sel secara vertikal.
Atribut ukuran widget memungkinkan Anda menentukan ukuran default untuk widget dan memberikan batas bawah dan atas pada ukuran widget. Dalam konteks ini, ukuran default widget adalah ukuran yang dimiliki widget saat pertama kali ditambahkan ke layar utama.
Tabel berikut menjelaskan atribut <appwidget-provider>
yang berkaitan dengan ukuran widget:
Atribut dan deskripsi | |
---|---|
targetCellWidth dan
targetCellHeight (Android 12),
minWidth dan minHeight |
targetCellWidth dan
targetCellHeight , serta minWidth dan
minHeight —agar aplikasi Anda dapat menggunakan
minWidth dan minHeight jika perangkat pengguna
tidak mendukung targetCellWidth dan
targetCellHeight . Jika didukung, atribut
targetCellWidth dan targetCellHeight
lebih diutamakan daripada atribut minWidth dan minHeight .
|
minResizeWidth dan
minResizeHeight |
Menentukan ukuran minimum absolut widget. Nilai ini menentukan
ukuran yang akan menjadikan widget tidak terbaca atau tidak dapat dipakai jika berada di bawahnya. Penggunaan
atribut ini memungkinkan pengguna mengubah ukuran widget ke ukuran yang lebih kecil
daripada ukuran widget default. Atribut minResizeWidth diabaikan jika lebih besar dari minWidth atau jika pengubahan ukuran secara horizontal tidak diaktifkan. Lihat
resizeMode . Demikian pula, atribut
minResizeHeight diabaikan jika lebih besar dari
minHeight atau jika pengubahan ukuran secara vertikal tidak diaktifkan. |
maxResizeWidth dan
maxResizeHeight |
Tentukan ukuran maksimum widget yang direkomendasikan. Jika nilai bukan
kelipatan dimensi sel petak, nilai akan dibulatkan ke atas ke
ukuran sel terdekat. Atribut maxResizeWidth diabaikan jika
lebih kecil dari minWidth atau jika pengubahan ukuran horizontal tidak
diaktifkan. Lihat resizeMode . Demikian pula,
atribut maxResizeHeight diabaikan jika lebih besar
dari minHeight atau jika pengubahan ukuran secara vertikal tidak diaktifkan.
Diperkenalkan di Android 12. |
resizeMode |
Menentukan aturan yang menjadikan ukuran widget dapat diubah. Anda dapat menggunakan atribut ini untuk membuat widget layar utama dapat diubah ukurannya secara horizontal, vertikal, atau pada kedua sumbu. Pengguna menyentuh lama widget untuk menampilkan tuas pengubah ukuran,
lalu menarik tuas horizontal atau vertikal untuk mengubah ukurannya pada
petak tata letak. Nilai untuk atribut resizeMode mencakup
horizontal , vertical , dan none . Untuk
mendeklarasikan widget dapat diubah ukurannya secara horizontal dan vertikal, gunakan
horizontal|vertical . |
Contoh
Untuk menggambarkan pengaruh atribut dalam tabel sebelumnya terhadap ukuran widget, asumsikan spesifikasi berikut:
- Sel petak memiliki lebar 30 dp dan tinggi 50 dp.
- Spesifikasi atribut berikut diberikan:
<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" />
Mulai dengan Android 12:
Gunakan atribut targetCellWidth
dan targetCellHeight
sebagai ukuran
default widget.
Ukuran widget adalah 2x2 secara default. Widget dapat diubah ukurannya menjadi 2x1 atau hingga 4x3.
Android 11 dan yang lebih lama:
Gunakan atribut minWidth
dan minHeight
untuk menghitung ukuran default
widget.
Lebar default = Math.ceil(80 / 30)
= 3
Tinggi default = Math.ceil(80 / 50)
= 2
Ukuran widget adalah 3x2 secara default. Widget dapat diubah ukurannya menjadi 2x1 atau hingga layar penuh.
Atribut widget tambahan
Tabel berikut menjelaskan atribut <appwidget-provider>
yang berkaitan dengan kualitas selain ukuran widget.
Atribut dan deskripsi | |
---|---|
updatePeriodMillis |
Menentukan seberapa sering framework widget meminta update dari
AppWidgetProvider dengan memanggil metode callback
onUpdate() . Update yang sebenarnya belum tentu terjadi tepat waktu dengan nilai ini, dan sebaiknya Anda mengupdate sesering mungkin, tetapi tidak lebih dari satu kali dalam satu jam, untuk menghemat baterai.
Untuk daftar lengkap pertimbangan dalam memilih periode update yang sesuai, lihat Pengoptimalan untuk memperbarui konten widget. |
initialLayout |
Menunjuk ke resource tata letak yang menentukan tata letak widget. |
configure |
Menentukan aktivitas yang diluncurkan saat pengguna menambahkan widget, sehingga mereka dapat mengonfigurasi properti widget. Lihat Mengizinkan pengguna mengonfigurasi widget. Mulai Android 12, aplikasi Anda dapat melewati konfigurasi awal. Lihat Menggunakan konfigurasi default widget untuk mengetahui detailnya. |
description |
Menentukan deskripsi untuk alat pilih widget yang akan ditampilkan untuk widget Anda. Diperkenalkan di Android 12. |
previewLayout (Android 12)
dan previewImage (Android 11 dan yang lebih lama) |
previewImage
dan previewLayout agar aplikasi Anda dapat melakukan penggantian
ke penggunaan previewImage jika perangkat pengguna tidak mendukung
previewLayout . Untuk mengetahui detail selengkapnya, lihat
Kompatibilitas mundur dengan pratinjau widget yang skalabel.
|
autoAdvanceViewId |
Menentukan ID tampilan sub-tampilan widget yang dimajukan secara otomatis oleh host widget. |
widgetCategory |
Mendeklarasikan apakah widget Anda dapat ditampilkan di layar utama
(home_screen ), layar kunci (keyguard ), atau
keduanya. Untuk Android 5.0 dan yang lebih tinggi, hanya home_screen yang valid.
|
widgetFeatures |
Mendeklarasikan fitur yang didukung oleh widget. Misalnya, jika Anda ingin
widget menggunakan konfigurasi default saat pengguna menambahkannya, tentukan
configuration_optional
dan
reconfigurable
sekaligus. Tindakan ini akan mengabaikan peluncuran aktivitas konfigurasi setelah pengguna
menambahkan widget. Pengguna masih dapat
mengonfigurasi ulang widget
setelahnya. |
Menggunakan class AppWidgetProvider untuk menangani siaran widget
Class AppWidgetProvider
menangani siaran widget dan memperbarui widget sebagai respons terhadap peristiwa siklus proses widget. Bagian berikut menjelaskan cara
mendeklarasikan AppWidgetProvider
dalam manifes, lalu menerapkannya.
Mendeklarasikan widget dalam manifes
Pertama, deklarasikan class AppWidgetProvider
di file AndroidManifest.xml
aplikasi Anda, seperti yang ditunjukkan dalam contoh berikut:
<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>
Elemen <receiver>
memerlukan atribut android:name
, yang menentukan
AppWidgetProvider
yang digunakan oleh widget. Komponen tidak boleh diekspor
kecuali jika proses terpisah perlu menyiarkan ke AppWidgetProvider
Anda, yang
biasanya tidak terjadi.
Elemen <intent-filter>
harus menyertakan elemen <action>
dengan atribut
android:name
. Atribut ini menentukan bahwa AppWidgetProvider
menerima siaran
ACTION_APPWIDGET_UPDATE
. Siaran ini merupakan satu-satunya yang harus Anda deklarasikan secara eksplisit. AppWidgetManager
secara otomatis mengirimkan semua siaran widget lainnya ke AppWidgetProvider
sesuai
kebutuhan.
Elemen <meta-data>
menentukan resource AppWidgetProviderInfo
dan
memerlukan atribut berikut:
android:name
: menentukan nama metadata. Gunakanandroid.appwidget.provider
untuk mengidentifikasi data sebagai deskriptorAppWidgetProviderInfo
.android:resource
: menentukan lokasi resourceAppWidgetProviderInfo
.
Mengimplementasikan class AppWidgetProvider
Class AppWidgetProvider
memperluas
BroadcastReceiver
sebagai
class praktis untuk menangani siaran widget. Widget ini hanya menerima siaran
peristiwa yang relevan dengan widget, seperti saat widget diupdate,
dihapus, diaktifkan, dan dinonaktifkan. Saat peristiwa siaran ini terjadi, metode
AppWidgetProvider
berikut dipanggil:
onUpdate()
- Metode ini dipanggil untuk mengupdate widget pada interval yang ditentukan oleh atribut
updatePeriodMillis
dalamAppWidgetProviderInfo
. Lihat tabel yang menjelaskan atribut widget tambahan di halaman ini untuk mengetahui informasi selengkapnya. - Metode ini juga dipanggil saat pengguna menambahkan widget, sehingga melakukan penyiapan
penting seperti menentukan pengendali peristiwa untuk objek
View
atau memulai tugas untuk memuat data yang akan ditampilkan di widget. Namun, jika Anda mendeklarasikan aktivitas konfigurasi tanpa flagconfiguration_optional
, metode ini tidak dipanggil saat pengguna menambahkan widget, tetapi dipanggil untuk update berikutnya. Aktivitas konfigurasi bertanggung jawab untuk melakukan update pertama saat konfigurasi selesai. Lihat Memungkinkan pengguna mengonfigurasi widget aplikasi untuk mengetahui informasi selengkapnya. - Callback yang paling penting adalah
onUpdate()
. Lihat Menangani peristiwa dengan classonUpdate()
di halaman ini untuk mengetahui informasi selengkapnya. onAppWidgetOptionsChanged()
Callback ini dipanggil saat widget pertama kali ditempatkan dan setiap kali ukuran widget diubah. Gunakan callback ini untuk menampilkan atau menyembunyikan konten berdasarkan rentang ukuran widget. Dapatkan rentang ukuran—dan, mulai di Android 12, daftar kemungkinan ukuran yang dapat diambil oleh instance widget—dengan memanggil
getAppWidgetOptions()
, yang akan menampilkanBundle
yang menyertakan hal berikut:OPTION_APPWIDGET_MIN_WIDTH
: berisi batas bawah pada lebar, dalam satuan dp, dari instance widget.OPTION_APPWIDGET_MIN_HEIGHT
: berisi batas bawah pada tinggi, dalam satuan dp, dari instance widget.OPTION_APPWIDGET_MAX_WIDTH
: berisi batas atas pada lebar, dalam satuan dp, dari instance widget.OPTION_APPWIDGET_MAX_HEIGHT
: berisi batas atas pada tinggi, dalam satuan dp, dari instance widget.OPTION_APPWIDGET_SIZES
: berisi daftar kemungkinan ukuran (List<SizeF>
), dalam unit dp, yang dapat digunakan oleh instance widget. Diperkenalkan di Android 12.
onDeleted(Context, int[])
Callback ini dipanggil setiap kali widget dihapus dari host widget.
onEnabled(Context)
Callback ini dipanggil saat instance widget dibuat untuk pertama kalinya. Misalnya, jika pengguna menambahkan dua instance widget Anda, callback ini hanya dipanggil pada pembuatan pertama. Jika Anda perlu membuka database baru atau melakukan penyiapan lain yang hanya perlu dilakukan sekali untuk semua instance widget, ini merupakan tempat yang tepat untuk melakukannya.
onDisabled(Context)
Callback ini dipanggil saat instance terakhir widget Anda dihapus dari host widget. Pada tahap ini, Anda akan menghapus semua pekerjaan yang dilakukan di
onEnabled(Context)
, seperti menghapus database sementara.onReceive(Context, Intent)
Callback ini dipanggil untuk setiap siaran dan sebelum setiap metode callback sebelumnya. Biasanya, Anda tidak perlu menerapkan metode ini, karena penerapan
AppWidgetProvider
default akan memfilter semua siaran widget dan memanggil metode sebelumnya yang sesuai.
Anda harus mendeklarasikan penerapan class AppWidgetProvider
sebagai penerima siaran menggunakan elemen <receiver>
dalam AndroidManifest
. Lihat Mendeklarasikan widget dalam manifes di halaman ini untuk mengetahui informasi selengkapnya.
Menangani peristiwa dengan class onUpdate()
Callback AppWidgetProvider
yang paling penting adalah onUpdate()
, karena dipanggil saat setiap widget ditambahkan ke host, kecuali jika Anda menggunakan aktivitas konfigurasi tanpa tanda configuration_optional
. Jika widget Anda menerima peristiwa interaksi pengguna, daftarkan pengendali peristiwa dalam callback ini. Jika
widget Anda tidak membuat file atau database sementara, atau melakukan pekerjaan lain
yang perlu dihapus, onUpdate()
mungkin merupakan satu-satunya metode callback yang
perlu Anda tentukan.
Misalnya, jika Anda ingin widget dengan tombol yang meluncurkan aktivitas saat
diketuk, Anda dapat menggunakan penerapan AppWidgetProvider
berikut:
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); } } }
AppWidgetProvider
ini hanya menentukan metode onUpdate()
, menggunakannya untuk
membuat PendingIntent
yang meluncurkan
Activity
dan melampirkannya ke tombol
widget menggunakan setOnClickPendingIntent(int,
PendingIntent)
. Hal ini mencakup loop yang melakukan iterasi melalui setiap entri
di appWidgetIds
, yang merupakan array ID yang mengidentifikasi setiap widget yang dibuat oleh
penyedia ini. Jika pengguna membuat lebih dari satu instance widget, maka
semua instance akan diupdate secara bersamaan. Namun, hanya satu jadwal updatePeriodMillis
yang dikelola untuk semua instance widget. Misalnya, jika jadwal update
ditetapkan setiap dua jam, dan instance kedua widget ditambahkan
satu jam setelah instance pertama, maka keduanya akan diupdate pada periode yang ditentukan oleh
instance pertama, dan periode update kedua akan diabaikan. Keduanya diperbarui setiap dua jam, bukan setiap jam.
Lihat class contoh ExampleAppWidgetProvider.java
untuk mengetahui detail selengkapnya.
Menerima intent siaran widget
AppWidgetProvider
adalah class praktis. Jika ingin menerima siaran widget secara langsung, Anda dapat menerapkan BroadcastReceiver
sendiri atau mengganti callback
onReceive(Context,Intent)
. Berikut adalah intent yang perlu Anda perhatikan:
ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED
Membuat tata letak widget
Anda harus menentukan tata letak awal untuk widget Anda dalam XML dan menyimpannya di
direktori res/layout/
project. Lihat Panduan
desain untuk mengetahui detailnya.
Pembuatan tata letak widget cukup mudah jika Anda memahami
tata letak. Namun, perlu diketahui bahwa tata letak
widget didasarkan pada RemoteViews
,
yang tidak mendukung setiap jenis tata letak atau widget tampilan. Anda tidak dapat menggunakan tampilan kustom atau subclass tampilan yang didukung oleh RemoteViews
.
RemoteViews
juga mendukung ViewStub
,
yang merupakan View
tidak terlihat berukuran nol yang dapat Anda gunakan untuk meng-inflate resource tata letak secara lambat saat runtime.
Dukungan untuk perilaku stateful
Android 12 menambahkan dukungan untuk perilaku stateful menggunakan komponen yang ada berikut:
Widget tetap stateless. Aplikasi Anda harus menyimpan status dan mendaftar peristiwa perubahan status.

Contoh kode berikut menunjukkan cara menerapkan komponen ini.
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));
Sediakan dua tata letak: satu menargetkan perangkat yang menjalankan Android 12 atau yang lebih tinggi di res/layout-v31
, dan yang lain menargetkan Android 11 atau yang lebih rendah di folder res/layout
default.
Menerapkan sudut bulat
Android 12 memperkenalkan parameter sistem berikut untuk menyetel radius sudut bulat widget Anda:
system_app_widget_background_radius
: radius sudut latar belakang widget, yang tidak pernah lebih besar dari 28 dp.Radius dalam, yang dapat dihitung dari radius luar dan padding. Lihat cuplikan berikut:
/** * Applies corner radius for views that are visually positioned [widgetPadding]dp inside of the * widget background. */ @Composable fun GlanceModifier.appWidgetInnerCornerRadius(widgetPadding: Dp): GlanceModifier { if (Build.VERSION.SDK_INT < 31) { return this } val resources = LocalContext.current.resources // get dimension in float (without rounding). val px = resources.getDimension(android.R.dimen.system_app_widget_background_radius) val widgetBackgroundRadiusDpValue = px / resources.displayMetrics.density if (widgetBackgroundRadiusDpValue < widgetPadding.value) { return this } return this.cornerRadius(Dp(widgetBackgroundRadiusDpValue - widgetPadding.value)) }
Untuk menghitung radius yang sesuai untuk konten dalam widget, gunakan formula berikut: systemRadiusValue - widgetPadding
Widget yang memangkas kontennya ke bentuk non-persegi panjang harus menggunakan
@android:id/background
sebagai ID tampilan dari tampilan latar belakang yang memiliki
android:clipToOutline
yang ditetapkan ke true
.
Pertimbangan penting untuk sudut tumpul
- Peluncur pihak ketiga dan produsen perangkat dapat mengganti
parameter
system_app_widget_background_radius
agar lebih kecil dari 28 dp. Jika widget Anda tidak menggunakan
@android:id/background
atau menentukan latar belakang yang memangkas kontennya berdasarkan garis luar—denganandroid:clipToOutline
yang ditetapkan ketrue
—peluncur secara otomatis mengidentifikasi latar belakang dan memangkas widget menggunakan persegi panjang dengan sudut bulat yang ditetapkan ke radius sistem.Bentuk non-persegi panjang harus berada dalam penampung pengubahan ukuran persegi panjang bulat agar tidak terpotong.
Mulai Android 16, nilai sistem AOSP untuk
system_app_widget_background_radius
adalah24dp
. Peluncur dan produsen perangkat dapat memangkas widget kesystem_app_widget_background_radius
.Konten dalam widget harus memiliki padding yang cukup untuk mendukung nilai radius
system_app_widget_background_radius
hingga28dp
agar tidak memotong konten oleh sudut bulat.
Untuk kompatibilitas widget dengan versi Android sebelumnya, sebaiknya tentukan atribut kustom dan gunakan tema kustom untuk menggantinya di Android 12, seperti yang ditunjukkan dalam contoh file XML berikut:
/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" />