Widget, iOS veya Android ana ekranında, uygulamayı açmadan güncel bilgileri gösteren kompakt bir kullanıcı arayüzü öğesidir. Widget'lar iOS 14'te (2020) SwiftUI üzerinde WidgetKit çerçevesiyle ortaya çıktı ve Android'de sürüm 1.5'ten itibaren Kotlin veya Java üzerinde AppWidgetProvider aracılığıyla mevcuttur. Kullanıcının ana ekranda doğrudan hava durumunu, döviz kurunu, takvimi, notları veya görev durumunu görmesini sağlayarak zaman kazandırır ve etkileşimi basitleştirir. Apple'a göre, kullanıcılar widget'larla günde ortalama 4–6 kez etkileşime girer ve ana ekrana bir widget yerleştirmek uygulama etkileşimini %20–30 artırır. Android için bu rakamlar benzerdir. Kod örnekleriyle her iki platformda widget'ların nasıl çalıştığını inceleyelim.
Önemli Noktalar
Widget, bir mobil cihazın ana ekranına yerleştirilen, bir uygulamadan güncel bilgileri görüntülemek için kullanılan kompakt bir kullanıcı arayüzü öğesidir. Tam bir uygulamanın aksine, widget başlatma gerektirmez — kullanıcı ekranı kilit açtıktan hemen sonra verileri görür. Bu kavram masaüstü işletim sistemlerinden (macOS Dashboard, Windows Sidebar) gelmektedir ve mobil ortamda Android, ilk sürümünden (Android 1.5 Cupcake, 2009) itibaren widget desteğini sunarken, Apple bunları yalnızca iOS 14'te eklemiştir.
Teknik uygulama platformlara göre farklılık gösterir. iOS widget'ı, Xcode'da ayrı bir hedeftir, Widget Extension olarak derlenir ve kendi sürecinde çalışır. Android widget'ı, AppWidgetProvider'ı genişleten bir BroadcastReceiver'dır ve düzeni RemoteViews aracılığıyla oluşturur. Her iki platform da performans ve bellek üzerinde katı kısıtlamalar uygular: sınırlar aşılırsa sistem widget'ı kaldırabilir. iOS, widget'ları 30–50 MB ve timeline oluşturma süresini 10 saniye ile sınırlar. Android — updatePeriodMillis ile 30 dakikayı aşmayan güncelleme aralığı ve onUpdate takılırsa zorla sonlandırma.
Smart Stack iOS'ta ve yığınlar Android'de, kullanıcının birden çok widget'ı tek bir ana ekran yuvasında gruplamasına olanak tanır. Cihaz, günün saatine, konuma veya kullanıcı etkinliğine bağlı olarak görüntülenen widget'ı otomatik olarak değiştirir. Örneğin, sabah takvim gösterilir, gündüz — hava durumu, akşam — notlar. Geliştiriciler için bu, widget'ın bir yığının parçası olarak doğru çalışması ve sürekli görüntülemeye bağımlı olmaması gerektiği anlamına gelir.
WidgetKit, iOS 14+, iPadOS 14+ ve macOS 11+'te widget oluşturmak için Apple'ın çerçevesidir. Widget'lar, SwiftUI ve içerik güncellemesi için TimelineProvider mekanizmasını kullanarak Swift ile yazılır. WidgetKit mimarisi üç bileşen içerir: TimelineProvider — girdilerle bir zaman çizelgesi oluşturan veri kaynağı; Widget Entry View — bir girdiye dayalı içerik görüntüleyen SwiftUI View; Widget Configuration — widget türü, boyutları ve ailelerinin açıklaması.
WidgetKit güncellemeleri otomatik olarak yönetir — geliştirici, sistemin izin verdiğinden daha sık widget güncellemesi zorlayamaz. Apple, cihazdaki tüm widget'lar arasında dağıtılan bir güncelleme bütçesi kullanır. Minimum aralık 15–30 dakikadır. Kritik veriler için (örneğin, teslimat durumu), push-to-refresh kullanılır — ilgili bir gelecek tarihle push bildirimi gönderilir, ardından WidgetKit yeni bir zaman çizelgesi ister. iOS 17'den itibaren widget'lar, App Intents aracılığıyla etkileşimliliği destekler — kullanıcılar uygulamayı açmadan widget içindeki düğmelere basabilir.
| Boyut | iOS (pt) | İçerik |
|---|---|---|
| Small | 170 × 170 | 1–2 gösterge: sıcaklık, döviz kuru |
| Medium | 360 × 170 | 2–4 gösterge: 5 günlük tahmin, liste |
| Large | 360 × 380 | 5–10 gösterge: takvim, haber akışı |
AppWidgetProvider, Android'de widget oluşturmak için temel sınıftır ve API level 3'ten beri Android SDK'nın bir parçasıdır. Android widget'ı, sistemden güncelleme, etkinleştirme ve devre dışı bırakma olaylarını alan bir BroadcastReceiver'dır. iOS'ta widget'ın kendi motorunda SwiftUI ile oluşturulmasının aksine, Android RemoteViews kullanır — sistem sürecinde (başlatıcı) oluşturulan sınırlı View bileşenleri kümesi. Özel View'lar, karmaşık animasyonlar veya UI kitaplıkları kullanılamaz.
Android widget iş akışı dört aşamadan oluşur. Yapılandırma — ekrana widget eklenirken, sistem kullanıcının ayarları seçtiği bir yapılandırma Activity'si başlatabilir. Güncelleme — sistem, belirtilen aralıkta (minimum 30 dakika) veya WorkManager aracılığıyla uygulamadan gelen sinyal üzerine onUpdate()'i çağırır. Oluşturma — sağlayıcı, güncel verilerle RemoteViews oluşturur ve bunları AppWidgetManager aracılığıyla iletir. Dokunma işleme — widget, düğmeler için PendingIntent'i destekler: tıklama bir Activity açar veya bir eylem gerçekleştirir. Android 12'den itibaren widget'lar, yuvarlak köşeler, uyarlanabilir Material You renkleri ve dinamik boyut değiştirme desteği kazanmıştır.
WidgetKit ve SwiftUI kullanarak Swift'te bir hava durumu widget'ı oluşturalım. Proje, Xcode'da Dosya → Yeni → Hedef → Widget Eklentisi aracılığıyla eklenen bir Widget Extension hedefi içermelidir.
import WidgetKit
import SwiftUI
// 1. Widget için veri modeli
struct WeatherEntry: TimelineEntry {
let date: Date
let temperature: Int
let condition: String
}
// 2. TimelineProvider — veri sağlayıcı
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), temperature: 22, condition: "Güneşli")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Güneşli")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let now = Date()
let entry = WeatherEntry(date: now, temperature: 20, condition: "Bulutlu")
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
// 3. Görüntüleme için SwiftUI View
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text("Hava durumu").font(.caption).foregroundColor(.secondary)
HStack {
Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
Spacer()
Text(entry.condition).font(.body)
}
}.padding()
}
}
// 4. Widget yapılandırması
@main
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
WeatherWidgetEntryView(entry: entry)
}
.configurationDisplayName("Hava durumu")
.description("Geçerli sıcaklığı gösterir")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Önemli noktalar: TimelineProvider ne zaman ve hangi verilerin gösterileceğini belirler; getTimeline, .after(nextUpdate) güncelleme politikasıyla bir zaman çizelgesi oluşturur; StaticConfiguration sağlayıcıyı View'a bağlar. Dinamik veriler için, özel parametrelerle IntentConfiguration kullanılır.
AppWidgetProvider ve RemoteViews ile Kotlin'de benzer bir hava durumu widget'ı uygulayalım.
// WeatherWidgetProvider.kt
class WeatherWidgetProvider : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
override fun onAppWidgetOptionsChanged(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
newOptions: Bundle
) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
companion object {
fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
val temperature = 20
val condition = "Bulutlu"
val views = RemoteViews(
context.packageName, R.layout.widget_weather
).apply {
setTextViewText(R.id.tv_temperature, "$temperature°")
setTextViewText(R.id.tv_condition, condition)
setOnClickPendingIntent(
R.id.widget_root, PendingIntent.getActivity(
context, 0,
Intent(context, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
)
}
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
}
// AndroidManifest — sağlayıcı kaydı
<receiver android:name=".WeatherWidgetProvider" 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/widget_weather_info" />
</receiver>
widget_weather_info.xml dosyası minimum boyutları, aralığı ve düzeni ayarlar: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 saat). RemoteViews yalnızca desteklenen bileşenleri kullanır: LinearLayout, TextView, ImageView. Özel View'lar ve ConstraintLayout, Android 5.0'dan itibaren kullanılabilir. GlanceLayout — RemoteViews için deneysel Compose tabanlı bir yaklaşım — Android 15'te ortaya çıkmıştır.
Sıkça Sorulan Sorular
iOS WidgetKit, üç sabit boyut (small, medium, large) ve sistem bütçesiyle TimelineProvider aracılığıyla güncelleme sunar. Android AppWidgetProvider esnek hücre tabanlı boyutlar, işleme için RemoteViews ve updatePeriodMillis veya WorkManager aracılığıyla güncelleme kullanır.
iOS'ta, sistem güncellemeleri kontrol eder — minimum aralık 15–30 dakikadır, kritik veriler için push-to-refresh kullanılır. Android'de aralık, updatePeriodMillis'te (minimum 30 dakika) veya arka plan görevleri için WorkManager aracılığıyla ayarlanır.
iOS, small (170x170pt), medium (360x170pt) ve large (360x380pt) boyutlarını destekler. Android esnek bir hücre ızgarası kullanır: 2x1'den 5x5'e kadar, boyut başlatıcıya ve işletim sistemi sürümüne bağlıdır.
iOS'ta, widget içinde animasyonlar mevcut değildir — bunlar statik öğelerdir. Android RemoteViews, setFloat() ve ViewPropertyAnimator aracılığıyla temel animasyonları destekler, ancak karmaşık animasyonlar mevcut değildir.
Doğru uygulamayla — hayır. Sistem widget kaynaklarını sıkı bir şekilde sınırlar: iOS'ta — güncelleme ve bellek bütçesi (30–50 MB), Android'de — minimum güncelleme aralığı. Sorunlu widget'lar sistem tarafından zorla sonlandırılır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun