Aşağıdaki bölümlerde, Glance ile temel bir uygulama widget'ının nasıl oluşturulacağı açıklanmaktadır.
Manifest'te AppWidget bildirme
Kurulum adımlarını tamamladıktan sonra uygulamanızda AppWidget ve meta verilerini tanımlayın.
AppWidgetalıcısınıGlanceAppWidgetReceivertarihinden itibaren uzatın:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { override val glanceAppWidget: GlanceAppWidget = TODO("Create GlanceAppWidget") }
Uygulama widget'ının sağlayıcısını
AndroidManifest.xmldosyanıza ve ilişkili meta veri dosyasına kaydedin:<receiver android:name=".glance.MyReceiver" android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/my_app_widget_info" /> </receiver>
AppWidgetProviderInfo meta verilerini ekleme
Ardından, @xml/my_app_widget_info dosyasında uygulama widget'ı bilgilerini oluşturmak ve tanımlamak için Widget oluşturma kılavuzunu uygulayın.
Glance'teki tek fark, initialLayout XML'nin olmamasıdır ancak bir tane tanımlamanız gerekir. Kitaplıkta sağlanan önceden tanımlanmış yükleme düzenini kullanabilirsiniz:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>
AppWidgetProviderInfo XML'ini bildirme
AppWidgetProviderInfo nesnesi, widget'ınızın temel özelliklerini tanımlar. XML meta veri kaynak dosyanızda (res/xml/my_app_widget_info.xml) AppWidgetProviderInfo öğesini bir <appwidget-provider> öğesi içinde tanımlayın:
<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/glance_default_loading_layout"
android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>
Widget boyutlandırma özellikleri
Varsayılan ana ekran, widget'ları penceresinde, tanımlı yüksekliği ve genişliği olan hücrelerden oluşan bir ızgaraya göre konumlandırır. Çoğu ana ekranda widget'lar yalnızca ızgara hücrelerinin tam sayı katları olan boyutlarda (ör. yatay olarak iki hücre, dikey olarak üç hücre) olabilir.
Widget boyutlandırma özellikleri, widget'ınız için varsayılan bir boyut belirtmenize ve widget'ın boyutu için alt ve üst sınırlar belirlemenize olanak tanır. Bu bağlamda, bir widget'ın varsayılan boyutu, ana ekrana ilk eklendiğinde aldığı boyuttur.
Aşağıdaki tabloda, widget boyutlandırmayla ilgili <appwidget-provider> özellikleri açıklanmaktadır:
| Özellikler ve açıklama | |
|---|---|
targetCellWidth ve
targetCellHeight (Android 12),
minWidth ve minHeight |
targetCellWidth ve targetCellHeight özelliklerini desteklemiyorsa uygulamanızın minWidth ve minHeight özelliklerini kullanabilmesi için her iki özellik grubunu da (targetCellWidth ve targetCellHeight ile minWidth ve minHeight) belirtmenizi öneririz. Destekleniyorsa targetCellWidth ve targetCellHeight özellikleri, minWidth ve minHeight özelliklerine göre öncelikli olur.
|
minResizeWidth ve
minResizeHeight |
Widget'ın mutlak minimum boyutunu belirtin. Bu değerler, widget'ın okunamayacak veya kullanılamayacak kadar küçük olduğu boyutu belirtir. Bu özellikleri kullanmak, kullanıcının widget'ı varsayılan widget boyutundan daha küçük bir boyuta yeniden boyutlandırmasına olanak tanır. minResizeWidth özelliği, minWidth değerinden büyükse veya yatay yeniden boyutlandırma etkinleştirilmemişse yoksayılır. resizeMode sayfasına göz atın. Benzer şekilde, minResizeHeight özelliği minHeight değerinden büyükse veya dikey yeniden boyutlandırma etkinleştirilmemişse yoksayılır. |
maxResizeWidth ve
maxResizeHeight |
Widget'ın önerilen maksimum boyutunu belirtin. Değerler, ızgara hücresi boyutlarının katı değilse en yakın hücre boyutuna yuvarlanır. maxResizeWidth özelliği, minWidth değerinden küçükse veya yatay yeniden boyutlandırma etkinleştirilmemişse yoksayılır. resizeMode sayfasına göz atabilirsiniz. Benzer şekilde, maxResizeHeight özelliği minHeight özelliğinden küçükse veya dikey yeniden boyutlandırma etkinleştirilmemişse yoksayılır.
Android 12'de kullanıma sunulmuştur. |
resizeMode |
Bir widget'ın yeniden boyutlandırılabileceği kuralları belirtir. Bu özelliği, ana ekran widget'larını yatay, dikey veya her iki eksende yeniden boyutlandırılabilir hale getirmek için kullanabilirsiniz. Kullanıcılar bir widget'a dokunup basılı tutarak yeniden boyutlandırma tutma yerlerini gösterir, ardından yatay veya dikey tutma yerlerini sürükleyerek düzen ızgarasındaki boyutunu değiştirir. resizeMode özelliğinin değerleri arasında horizontal, vertical ve none yer alır. Bir widget'ın yatay ve dikey olarak yeniden boyutlandırılabileceğini belirtmek için horizontal|vertical kullanın. |
Örnek
Yukarıdaki tablodaki özelliklerin widget boyutlandırmayı nasıl etkilediğini göstermek için aşağıdaki özellikleri varsayalım:
- Izgara hücresi 30 dp genişliğinde ve 50 dp yüksekliğindedir.
- Aşağıdaki özellik spesifikasyonu sağlanır:
<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" />
Android 12'den itibaren:
Widget'ın varsayılan boyutu olarak targetCellWidth ve targetCellHeight özelliklerini kullanın.
Widget'ın boyutu varsayılan olarak 2x2'dir. Widget'ın boyutu 2x1'e kadar küçültülebilir veya 4x3'e kadar büyütülebilir.
Android 11 ve önceki sürümler:
Widget'ın varsayılan boyutunu hesaplamak için minWidth ve minHeight özelliklerini kullanın.
Varsayılan genişlik = Math.ceil(80 / 30) = 3
Varsayılan yükseklik = Math.ceil(80 / 50) = 2
Widget'ın boyutu varsayılan olarak 3x2'dir. Widget'ı 2x1 boyutuna kadar küçültebilir veya tam ekran boyutuna kadar büyütebilirsiniz.
Ek widget özellikleri
Aşağıdaki tabloda, widget boyutlandırma dışındaki niteliklerle ilgili <appwidget-provider> özellikleri açıklanmaktadır.
| Özellikler ve açıklama | |
|---|---|
updatePeriodMillis |
Widget çerçevesinin, onUpdate() geri çağırma yöntemini çağırarak GlanceAppWidgetReceiver öğesinden ne sıklıkta güncelleme isteyeceğini tanımlar. Pilden tasarruf etmek için mümkün olduğunca seyrek (saatte en fazla bir kez) güncelleme yapmanızı öneririz.
Ayrıntılar için Glance durum yönetimi bölümündeki Widget'lar ne zaman güncellenir? bölümüne bakın. |
initialLayout |
Glance kullanıcı arayüzü bileşenleri oluşturulmadan önce widget'ın yükleme düzenini tanımlayan düzen kaynağını gösterir. Kitaplıkta sunulan önceden tanımlanmış yükleme düzenini kullanabilirsiniz: @layout/glance_default_loading_layout. |
configure |
Kullanıcı widget'ı eklediğinde başlatılan yapılandırma etkinliğini tanımlar. Kullanıcıların uygulama widget'larını yapılandırmasına izin verme kılavuzunu inceleyin. |
description |
Widget seçicinin widget'ınız için göstereceği açıklamayı belirtir. Android 12'de kullanıma sunulmuştur. |
previewLayout (Android 12)
ve previewImage (Android 11 ve önceki sürümler) |
|
autoAdvanceViewId |
Widget'ın ana makinesi tarafından otomatik olarak ilerletilen widget alt görünümünün görünüm kimliğini belirtir. |
widgetCategory |
Widget'ınızın ana ekranda (home_screen), kilit ekranında (keyguard) veya her ikisinde gösterilip gösterilemeyeceğini belirtir. Android 5.0 ve sonraki sürümler için yalnızca home_screen geçerlidir. |
widgetFeatures |
Widget tarafından desteklenen özellikleri bildirir. Örneğin, widget'ınızın yapılandırması isteğe bağlıysa hem configuration_optional hem de reconfigurable değerini belirtin. |
GlanceAppWidget kelimesinin tanımı
GlanceAppWidgetsınıfını genişleten veprovideGlanceyöntemini geçersiz kılan yeni bir sınıf oluşturun. Bu yöntem, widget'ınızı oluşturmak için gereken verileri yükleyebileceğiniz yöntemdir:class MyAppWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { // In this method, load data needed to render the AppWidget. // Use `withContext` to switch to another thread for long running // operations. provideContent { // create your AppWidget here Text("Hello World") } } }
GlanceAppWidgetReceivercihazınızdakiglanceAppWidgetuygulamasında örneklendirin:class MyAppWidgetReceiver : GlanceAppWidgetReceiver() { // Let MyAppWidgetReceiver know which GlanceAppWidget to use override val glanceAppWidget: GlanceAppWidget = MyAppWidget() }
Glance'i kullanarak bir AppWidget yapılandırdınız.
Farklı boyut gruplarında widget resim belleğini yönetme
Widget'ınız bitmap'leri veya content:// resim URI'lerini gösterdiğinde, toplam serileştirilmiş RemoteViews resim belleğini sistem sınırında (6 * width *
height bayt, Android 17 ve sonraki sürümlerde IllegalArgumentException ile zorunlu kılınır) tutmak için aşağıdakileri yapın:
provideContentöncesinde paylaşılan bitmap'lerin kodunu çözme: Widget'ınızSizeMode.ResponsiveveyaSizeMode.Exactkullanıyorsa Glance, herDpSizegrubu içinprovideContentlambda'yı bir kez çalıştırır.provideContentiçinde birBitmapkodunu çözmek, her paket için ayrı birBitmapörneği ayırarakRemoteViews.mBitmapCacheiçindeki bellek kullanımını artırır. Tüm grupların tek birBitmapreferansını paylaşması içinprovideContentişleminden önceprovideGlanceiçinde bir kez alt örneklenmiş bit eşlemlerin (opak resimler içinBitmap.Config.RGB_565) kodunu çözün.Eşleşen
ImageProvideriçe aktarma işlemini kullanın: Jetpack Glance, iki paket genelinde iki farklıImageProvideraşırı yükleme sağlar:- Bellek içi
ImageProvider(bitmap: Bitmap)veya drawable kaynakImageProvider(resId: Int)iletirkenimport androidx.glance.ImageProviderkullanın. - URI iletirken
import androidx.glance.appwidget.ImageProviderkullanınImageProvider(uri: Uri). Önbelleğe alınmış dosyaları birFileProviderURI'si üzerinden sunarken ana makinenin resmi oluşturabilmesi için yüklü herIntent.CATEGORY_HOMEbaşlatıcı paketineIntent.FLAG_GRANT_READ_URI_PERMISSIONizni verin.
- Bellek içi
Widget yayınlarını işlemek için GlanceAppWidgetReceiver sınıfını kullanma
GlanceAppWidgetReceiver, temel AppWidgetProvider'yi genişleterek widget yayınlarını ve platform durumu güncellemelerini koordine eder. Widget'ınız güncellendiğinde, silindiğinde, etkinleştirildiğinde veya devre dışı bırakıldığında platform etkinliklerini alır ve bunları Compose yaşam döngüsü isteklerine dönüştürür.
Manifest dosyasında widget tanımlama
GlanceAppWidgetReceiver sınıfı alt sınıfınızı AndroidManifest.xml dosyanızda yayın alıcısı olarak tanımlayın:
<receiver android:name="MyReceiver"
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/my_app_widget_info" />
</receiver>
<receiver> öğesi, alıcı sınıfını belirten android:name özelliğini gerektirir. Alıcı, <intent-filter> içindeki ACTION_APPWIDGET_UPDATE yayın işlemini kabul etmelidir.
<meta-data> öğesi, adını android.appwidget.provider olarak tanımlamalı ve android:resource özelliği, AppWidgetProviderInfo XML meta veri kaynağınızı (@xml/my_app_widget_info) işaret etmelidir.
GlanceAppWidgetReceiver sınıfını uygulama
Glance'te doğrudan AppWidgetProvider yerine GlanceAppWidgetReceiver sınıfını genişletirsiniz. Alıcınızı GlanceAppWidget örneğinize bağlayarak uygulayın. GlanceAppWidgetReceiver içinde kullanılabilen birincil geri çağırmalar aşağıdaki gibi çalışır:
onUpdate(): Oluşturma güncellemelerini yürütmek için Glance tarafından otomatik olarak geçersiz kılınır.onUpdatedeğerini manuel olarak geçersiz kılarsanız Glance'in oluşturma iş parçacıklarını başarıyla başlatmasına izin vermek içinsuper.onUpdateyöntemini çağırmanız gerekir.onAppWidgetOptionsChanged(): Widget ilk kez yerleştirildiğinde veya yeniden boyutlandırıldığında çağrılır. Glance, okuma seçenekleri paket öğelerini arka planda gruplandırır. Böylece düzeniniz, çalışma zamanı boyutlarına göre sorunsuz bir şekilde ayarlanır.onDeleted(Context, IntArray): Belirli bir widget örneği kullanıcı tarafından silindiğinde çağrılır.onEnabled(Context): Widget'ınızın ilk örneği başarıyla oluşturulduğunda tetiklenir. Global taşıma işlemleri için mükemmeldir.onDisabled(Context): Sağlayıcının son etkin örneği kaldırıldığında çağrılır.onReceive(Context, Intent): Belirli geri çağırma yöntemlerinden önce her platform yayınını engeller. Yazdığınız tüm özel alıcı mantıklarınınsuper.onReceive(context, intent)yöntemini çağırdığından emin olmanız gerekir. Glance, işleri otomatik olarak eşzamansız şekilde yönlendirdiğindengoAsyncyöntemini hiçbir zaman kendiniz çağırmamalısınız.
Widget yayın amaçlarını alma
GlanceAppWidgetReceiver, arka planda aşağıdaki temel platform widget'ı yayın intent'lerini filtreler ve işler:
ACTION_APPWIDGET_UPDATEACTION_APPWIDGET_DELETEDACTION_APPWIDGET_ENABLEDACTION_APPWIDGET_DISABLEDACTION_APPWIDGET_OPTIONS_CHANGED
Kullanıcı arayüzü oluşturma
Aşağıdaki snippet'te kullanıcı arayüzünün nasıl oluşturulacağı gösterilmektedir:
/* Import Glance Composables In the event there is a name clash with the Compose classes of the same name, you may rename the imports per https://kotlinlang.org/docs/packages.html#imports using the `as` keyword. import androidx.glance.Button import androidx.glance.layout.Column import androidx.glance.layout.Row import androidx.glance.text.Text */ class MyAppWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { // Load data needed to render the AppWidget. // Use `withContext` to switch to another thread for long running // operations. provideContent { // create your AppWidget here MyContent() } } @Composable private fun MyContent() { Column( modifier = GlanceModifier.fillMaxSize(), verticalAlignment = Alignment.Top, horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = "Where to?", modifier = GlanceModifier.padding(12.dp)) Row(horizontalAlignment = Alignment.CenterHorizontally) { Button( text = "Home", onClick = actionStartActivity<MyActivity>() ) Button( text = "Work", onClick = actionStartActivity<MyActivity>() ) } } } }
Yukarıdaki kod örneği şunları yapar:
- Üst düzeyde
Column, öğeler dikey olarak birbiri ardına yerleştirilir. Column, boyutunu kullanılabilir alana uyacak şekilde genişletir (GlanceModifieraracılığıyla) ve içeriğini en üste (verticalAlignment) hizalayıp yatay olarak ortalar (horizontalAlignment).Columniçeriği, lambda kullanılarak tanımlanır. Sıralama önemlidir.Columniçindeki ilk öğe,12.dpdolgulu birTextbileşenidir.- İkinci öğe, öğelerin yatay olarak birbiri ardına yerleştirildiği ve iki
Buttonsöğesinin yatay olarak ortalandığı (horizontalAlignment) birRowöğesidir. Son görüntü, kullanılabilir alana bağlıdır. Aşağıdaki resimde, bunun nasıl görünebileceğine dair bir örnek verilmiştir:
Bileşenlerin yerleşimini ve boyutunu değiştirmek için hizalama değerlerini değiştirebilir veya farklı değiştirici değerleri (ör. dolgu) uygulayabilirsiniz. Bileşenlerin, parametrelerin ve her sınıf için kullanılabilir değiştiricilerin tam listesi için referans belgelerine bakın.
Yuvarlatılmış köşeler kullanma
Android 12, uygulama widget'larınızın köşe yarıçaplarını dinamik olarak özelleştirmek için sistem parametreleri sunar:
system_app_widget_background_radius: Widget arka plan kapsayıcısının köşe yarıçapını belirtir (hiçbir zaman 28 dp'den büyük olamaz).- İç yarıçap: İçeriğin kırpılmasını önlemek için sistem arka plan ana hattına göre iç içeriğiniz için orantılı bir yarıçap hesaplayın:
systemRadiusValue - widgetPadding
Glance'te, GlanceModifier.cornerRadius(android.R.dimen.system_app_widget_background_radius) kullanarak köşe yarıçapı boyutlandırma özelliklerini oluşturma sırasında dinamik olarak uygulayabilirsiniz.
Android 11 (API düzeyi 30) veya daha eski sürümleri çalıştıran cihazlarda geriye dönük uyumluluk için özel özellikleri ve özel tema kaynağı yedeklerini uygulayın:
/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>