Halaman ini menjelaskan peningkatan kualitas ukuran widget dan fleksibilitas lebih besar yang diperkenalkan di Android 12 (level API 31). Artikel ini juga menjelaskan cara menentukan ukuran untuk widget Anda.
Menggunakan API yang dioptimalkan untuk ukuran dan tata letak widget
Mulai Android 12 (level API 31), Anda dapat memberikan atribut ukuran yang lebih disempurnakan dan tata letak yang fleksibel dengan melakukan hal berikut, seperti yang dijelaskan di bagian berikut:
Menyediakan tata letak responsif atau tata letak yang tepat.
Pada versi Android sebelumnya, Anda dapat memperoleh rentang ukuran
widget menggunakan tambahan
OPTION_APPWIDGET_MIN_WIDTH
,
OPTION_APPWIDGET_MIN_HEIGHT
,
OPTION_APPWIDGET_MAX_WIDTH
,
dan OPTION_APPWIDGET_MAX_HEIGHT
,
lalu memperkirakan ukuran widget, tetapi logika tersebut tidak berfungsi di semua
situasi. Untuk widget yang menargetkan Android 12 atau yang lebih tinggi, sebaiknya
berikan tata letak responsif atau tata letak
yang tepat.
Menentukan batasan ukuran widget tambahan
Android 12 menambahkan API yang memungkinkan Anda memastikan ukuran widget lebih andal di berbagai perangkat dengan berbagai ukuran layar.
Selain minWidth
yang ada,
minHeight
,
minResizeWidth
,
dan minResizeHeight
atribut, gunakan atribut baru appwidget-provider
berikut:
targetCellWidth
dantargetCellHeight
: menentukan ukuran target widget dari segi sel petak peluncur. Jika ditentukan, atribut ini digunakan sebagai gantiminWidth
atauminHeight
.maxResizeWidth
danmaxResizeHeight
: menentukan ukuran maksimum peluncur yang memungkinkan pengguna mengubah ukuran widget.
XML berikut menunjukkan cara menggunakan atribut ukuran.
<appwidget-provider
...
android:targetCellWidth="3"
android:targetCellHeight="2"
android:maxResizeWidth="250dp"
android:maxResizeHeight="110dp">
</appwidget-provider>
Menyediakan tata letak yang responsif
Jika tata letak perlu diubah sesuai ukuran widget, sebaiknya buat set tata letak kecil yang masing-masing valid untuk berbagai ukuran. Jika tidak memungkinkan, opsi lainnya adalah menyediakan tata letak berdasarkan ukuran widget yang tepat saat runtime, seperti yang dijelaskan di halaman ini.
Fitur ini memungkinkan penskalaan yang lebih lancar dan kesehatan sistem yang lebih baik secara keseluruhan, karena sistem tidak perlu mengaktifkan aplikasi setiap kali menampilkan widget dalam ukuran yang berbeda.
Contoh kode berikut menunjukkan cara memberikan daftar tata letak.
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); }
Asumsikan bahwa widget memiliki atribut berikut:
<appwidget-provider
android:minResizeWidth="160dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="250dp"
android:maxResizeHeight="200dp">
</appwidget-provider>
Cuplikan kode sebelumnya berarti sebagai berikut:
smallView
mendukung dari 160 dp (minResizeWidth
) × 110 dp (minResizeHeight
) hingga 160 dp × 199 dp (titik potong berikutnya - 1 dp).tallView
mendukung dari 160 dp × 200 dp hingga 214 dp (titik potong berikutnya - 1) × 200 dp.wideView
mendukung dari 215 dp × 110 dp (minResizeHeight
) hingga 250 dp (maxResizeWidth
) × 200 dp (maxResizeHeight
).
Widget Anda harus mendukung rentang ukuran dari minResizeWidth
×
minResizeHeight
hingga maxResizeWidth
× maxResizeHeight
. Dalam rentang itu, Anda dapat menentukan
titik potong untuk beralih tata letak.
![Contoh tata letak responsif](https://developer.android.com/static/images/appwidgets/size-range.gif?authuser=4&hl=id)
Menyediakan tata letak yang tepat
Jika kumpulan kecil tata letak responsif tidak memungkinkan, Anda dapat memberikan tata letak yang berbeda dan telah disesuaikan dengan ukuran widget yang ditampilkan tersebut. Ini biasanya berupa dua ukuran untuk ponsel (mode potret dan lanskap) dan empat ukuran untuk perangkat foldable.
Untuk menerapkan solusi ini, aplikasi Anda harus melakukan langkah-langkah berikut:
Kelebihan
AppWidgetProvider.onAppWidgetOptionsChanged()
yang dipanggil saat kumpulan ukuran berubah.Memanggil
AppWidgetManager.getAppWidgetOptions()
yang menampilkanBundle
yang berisi ukuran.Mengakses kunci
AppWidgetManager.OPTION_APPWIDGET_SIZES
dariBundle
.
Contoh kode berikut menunjukkan cara menyediakan tata letak yang persis.
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) { }
Menentukan ukuran untuk widget Anda
Setiap widget harus menentukan targetCellWidth
dan targetCellHeight
untuk perangkat
yang menjalankan Android 12 atau yang lebih tinggi—atau minWidth
dan minHeight
untuk semua
versi Android—yang menunjukkan jumlah ruang minimum yang digunakannya
secara default. Namun, saat pengguna menambahkan widget ke layar utama, widget tersebut biasanya akan menempati lebih dari lebar dan tinggi minimum yang Anda tentukan.
Layar utama Android menawarkan kepada pengguna petak ruang yang tersedia tempat mereka dapat
menempatkan widget dan ikon. Petak ini dapat bervariasi menurut perangkat; misalnya, banyak
handset menawarkan petak 5x4, dan tablet dapat menawarkan petak yang lebih besar. Saat widget
ditambahkan, widget akan direntangkan untuk menempati jumlah sel minimum,
secara horizontal dan vertikal, yang diperlukan guna memenuhi batasan untuk
targetCellWidth
dan targetCellHeight
pada perangkat yang menjalankan
Android 12 atau yang lebih tinggi, atau batasan minWidth
dan minHeight
pada
perangkat yang menjalankan Android 11 (level API 30) atau yang lebih rendah.
Lebar dan tinggi sel serta ukuran margin otomatis yang diterapkan ke widget dapat bervariasi di berbagai perangkat. Gunakan tabel berikut untuk memperkirakan secara kasar dimensi minimum widget Anda pada handset petak 5x4 standar, dengan mempertimbangkan jumlah sel petak yang Anda inginkan:
Jumlah sel (lebar x tinggi) | Ukuran yang tersedia dalam mode potret (dp) | Ukuran yang tersedia dalam mode lanskap (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 (118m - 16) | (142n - 15) x (66m - 15) |
Gunakan ukuran sel mode potret untuk menginformasikan nilai yang Anda berikan untuk
atribut minWidth
, minResizeWidth
, dan maxResizeWidth
. Demikian pula,
gunakan ukuran sel mode lanskap untuk menginformasikan nilai yang Anda berikan
untuk atribut minHeight
, minResizeHeight
, dan maxResizeHeight
.
Alasannya adalah karena lebar sel biasanya lebih kecil dalam mode potret daripada dalam mode lanskap—dan, demikian pula, tinggi sel biasanya lebih kecil dalam mode lanskap daripada dalam mode potret.
Misalnya, jika ingin lebar widget dapat diubah ukurannya menjadi satu sel di
Google Pixel 4, Anda harus menetapkan minResizeWidth
maksimal 56 dp
guna memastikan nilai untuk atribut minResizeWidth
lebih kecil
dari 57 dp—karena lebar sel minimal 57 dp dalam mode potret.
Demikian pula, jika ingin tinggi widget dapat diubah ukurannya dalam satu sel di
perangkat yang sama, Anda harus menetapkan minResizeHeight
maksimal 50 dp guna memastikan
nilai untuk atribut minResizeHeight
lebih kecil dari
51 dp—karena satu sel memiliki tinggi minimal 51 dp dalam mode lanskap.
Setiap widget dapat diubah ukurannya dalam rentang ukuran antara atribut
minResizeWidth
/minResizeHeight
dan maxResizeWidth
/maxResizeHeight
, yang berarti widget harus menyesuaikan dengan berbagai rentang ukuran di antara widget tersebut.
Misalnya, untuk menetapkan ukuran default widget pada penempatan, Anda dapat menetapkan atribut berikut:
<appwidget-provider
android:targetCellWidth="3"
android:targetCellHeight="2"
android:minWidth="180dp"
android:minHeight="110dp">
</appwidget-provider>
Artinya, ukuran default widget adalah sel 3x2, seperti yang ditentukan oleh
atribut targetCellWidth
dan targetCellHeight
—atau 180×110 dp, seperti
yang ditentukan oleh minWidth
dan minHeight
untuk perangkat yang menjalankan
Android 11 atau yang lebih rendah. Pada kasus yang terakhir, ukuran dalam sel dapat
bervariasi, tergantung perangkatnya.
Selain itu, untuk menetapkan rentang ukuran widget yang didukung, Anda dapat menetapkan atribut berikut:
<appwidget-provider
android:minResizeWidth="180dp"
android:minResizeHeight="110dp"
android:maxResizeWidth="530dp"
android:maxResizeHeight="450dp">
</appwidget-provider>
Seperti yang ditentukan oleh atribut sebelumnya, lebar widget dapat diubah ukurannya dari 180 dp menjadi 530 dp, dan tingginya dapat diubah dari 110 dp menjadi 450 dp. Widget ini kemudian dapat diubah ukurannya dari sel 3x2 ke 5x2, selama kondisi berikut ada:
- Perangkat memiliki petak 5x4.
- Pemetaan antara jumlah sel dan ukuran yang tersedia dalam dp mengikuti tabel yang menunjukkan estimasi dimensi minimum di halaman ini.
- Widget akan menyesuaikan dengan rentang ukuran tersebut.
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);
Asumsikan bahwa widget menggunakan tata letak responsif yang ditentukan dalam cuplikan kode
sebelumnya. Artinya, tata letak yang ditentukan sebagai
R.layout.widget_weather_forecast_small
digunakan dari 180 dp (minResizeWidth
) x
110 dp (minResizeHeight
) hingga 269x279 dp (titik potong berikutnya - 1). Demikian pula,
R.layout.widget_weather_forecast_medium
digunakan dari 270x110 dp hingga 270x279 dp,
dan R.layout.widget_weather_forecast_large
digunakan dari 270x280 dp hingga
530 dp (maxResizeWidth
) x 450 dp (maxResizeHeight
).
Saat pengguna mengubah ukuran widget, tampilannya akan berubah untuk beradaptasi dengan setiap ukuran dalam sel, seperti yang ditunjukkan pada contoh berikut.
![Contoh widget cuaca dalam ukuran petak 3x2 terkecil. UI menampilkan
nama lokasi (Tokyo), suhu (14°), dan simbol yang menunjukkan
cuaca sebagian berawan.](https://developer.android.com/static/images/appwidgets/weather-size-3x2.png?authuser=4&hl=id)
R.layout.widget_weather_forecast_small
.![Contoh widget cuaca dalam ukuran 'sedang' 4x2. Perubahan ukuran widget
dengan cara ini akan didasarkan pada semua UI dari ukuran widget sebelumnya,
serta menambahkan label 'Sebagian besar berawan' dan perkiraan suhu dari
pukul 16.00 hingga 19.00.](https://developer.android.com/static/images/appwidgets/weather-size-4x2.png?authuser=4&hl=id)
R.layout.widget_weather_forecast_medium
.![Contoh widget cuaca dalam ukuran 'sedang' 5x2. Perubahan ukuran widget
dengan cara ini akan menghasilkan UI yang sama dengan ukuran sebelumnya, tetapi
direntangkan sepanjang satu sel untuk menempati lebih banyak ruang horizontal.](https://developer.android.com/static/images/appwidgets/weather-size-5x2.png?authuser=4&hl=id)
R.layout.widget_weather_forecast_medium
.![Contoh widget cuaca dalam ukuran 'besar' 5x3. Perubahan ukuran widget
dengan cara ini akan dibuat berdasarkan semua UI dari ukuran widget sebelumnya,
dan akan menambahkan tampilan di dalam widget yang berisi perkiraan cuaca
pada hari Selasa dan Rabu. Simbol yang menunjukkan cuaca cerah atau hujan
serta suhu tinggi dan rendah untuk setiap hari.](https://developer.android.com/static/images/appwidgets/weather-size-5x3.png?authuser=4&hl=id)
R.layout.widget_weather_forecast_large
.![Contoh widget cuaca dalam ukuran 'besar' 5x4. Perubahan ukuran widget
dengan cara ini akan memanfaatkan semua UI dari ukuran widget sebelumnya,
serta menambahkan hari Kamis dan Jumat (dan simbol yang sesuai
yang menunjukkan jenis cuaca serta suhu tertinggi dan rendah
untuk setiap hari).](https://developer.android.com/static/images/appwidgets/weather-size-5x4.png?authuser=4&hl=id)
R.layout.widget_weather_forecast_large
.