Widget — iOS və ya Android ana ekranında yerləşən, proqramı açmadan aktual məlumatı göstərən kompakt istifadəçi interfeys elementidir. Vidjetlər iOS 14-də (2020) SwiftUI-də WidgetKit freymvorku ilə ortaya çıxdı və Android-də 1.5 versiyasından Kotlin və ya Java ilə AppWidgetProvider vasitəsilə mövcuddur. Onlar istifadəçiyə hava, valyuta məzənnəsi, təqvim, qeydlər və ya tapşırıq statusunu birbaşa home screen-də görməyə imkan verir, vaxta qənaət edir və qarşılıqlı əlaqəni sadələşdirir. Apple məlumatlarına görə, istifadəçilər vidjetlərlə gündə orta hesabla 4–6 dəfə qarşılıqlı əlaqədə olur, home screen-də vidjetin quraşdırılması proqrama cəlb olunmanı 20–30% artırır. Android üçün bu göstəricilər müqayisə olunandır. Hər iki platformada vidjetlərin necə qurulduğunu kod nümunələri ilə nəzərdən keçirək.
Əsas məqamlar
Widget — mobil cihazın ana ekranında proqramdan aktual məlumatı göstərmək üçün yerləşdirilən kompakt istifadəçi interfeys elementidir. Tam hüquqlu proqramdan fərqli olaraq, vidjet işə salma tələb etmir — istifadəçi ekranı açdıqdan dərhal sonra məlumatı görür. Konsepsiya masaüstü əməliyyat sistemlərindən (macOS Dashboard, Windows Sidebar) gəlir, mobil mühitdə isə Android vidjet dəstəyini ilk buraxılışından (Android 1.5 Cupcake, 2009) təqdim etdi, Apple isə onları yalnız iOS 14-də əlavə etdi.
Texniki tətbiq platformalarda fərqlənir. iOS vidjeti — Xcode-da ayrıca target, Widget Extension kimi kompilə olunur, öz prosesində işləyir. Android vidjeti — AppWidgetProvider-i genişləndirən BroadcastReceiver, layout-u RemoteViews vasitəsilə render edir. Hər iki platforma performans və yaddaşa ciddi məhdudiyyətlər qoyur: sistem limitlər aşıldıqda vidjeti silə bilər. iOS vidjeti 30–50 MB və timeline formalaşdırma müddətini 10 saniyə ilə məhdudlaşdırır. Android — updatePeriodMillis vasitəsilə yeniləmə intervalı 30 dəqiqədən tez olmamalıdır və onUpdate asılması halında məcburi dayandırma tətbiq edilir.
Smart Stack iOS-da və yığınlar Android-də istifadəçiyə bir neçə vidjeti home screen-də bir slota qruplaşdırmağa imkan verir. Cihaz günün vaxtı, yer və ya istifadəçi fəaliyyətindən asılı olaraq göstərilən vidjeti avtomatik dəyişir. Məsələn, səhər təqvim, gündüz hava, axşam qeydlər göstərilir. Tərtibatçı üçün bu o deməkdir ki, vidjet yığın tərkibində düzgün işləməli və daimi göstərilməyə etibar etməməlidir.
WidgetKit — iOS 14+, iPadOS 14+ və macOS 11+ üçün vidjetlər yaratmaq üçün Apple freymvorkudur. Vidjetlər SwiftUI və məzmunu yeniləmək üçün TimelineProvider mexanizmindən istifadə edərək Swift-də yazılır. WidgetKit arxitekturası üç komponentdən ibarətdir: TimelineProvider — qeydlərlə zaman şkalası formalaşdıran məlumat mənbəyi; Widget Entry View — qeyd əsasında məzmunu göstərən SwiftUI View; Widget Configuration — vidjetin tipini, ölçülərini və ailələrini təsvir edən konfiqurasiya.
WidgetKit yeniləməni özü idarə edir — tərtibatçı sistemin icazə verdiyindən daha tez-tez vidjeti yeniləyə bilməz. Apple cihazdakı bütün vidjetlər arasında bölüşdürülən yeniləmə büdcəsindən istifadə edir. Minimum interval — 15–30 dəqiqə. Kritik məlumatlar üçün (məsələn, çatdırılma statusu) push-to-refresh istifadə olunur — gələcəkdə müvafiq tarixlə push bildirişi göndərilir, bundan sonra WidgetKit yeni timeline tələb edir. iOS 17-dən etibarən vidjetlər App Intents vasitəsilə interaktivliyi dəstəkləyir — istifadəçi proqramı açmadan vidjet daxilində düymələri basa bilər.
| Ölçü | iOS (pt) | Məzmun |
|---|---|---|
| Small | 170 × 170 | 1–2 göstərici: temperatur, valyuta məzənnəsi |
| Medium | 360 × 170 | 2–4 göstərici: 5 günlük proqnoz, siyahı |
| Large | 360 × 380 | 5–10 göstərici: təqvim, xəbər lent |
AppWidgetProvider — Android-də vidjetlər yaratmaq üçün API level 3-dən Android SDK-ya daxil olan əsas sinifdir. Android vidjeti — sistemdən yeniləmə, aktivləşdirmə və deaktivləşdirmə hadisələrini alan BroadcastReceiver-dir. iOS-da vidjet SwiftUI ilə öz mühərrikində çəkildiyi halda, Android RemoteViews — sistem prosesində (launçerdə) render edilən məhdud View komponentlər dəstindən istifadə edir. Xüsusi View-lər, mürəkkəb animasiyalar və ya UI kitabxanaları istifadə edilə bilməz.
Android vidjetinin iş sxemi dörd mərhələdən ibarətdir. Konfiqurasiya — vidjet ekrana əlavə edilərkən sistem istifadəçinin parametrləri seçdiyi konfiqurasiya Activity-ni işə sala bilər. Yeniləmə — sistem onUpdate()-i müəyyən intervalda (minimum 30 dəqiqə) və ya WorkManager vasitəsilə proqramdan siqnal ilə çağırır. Render etmə — provayder cari məlumatlarla RemoteViews yaradır və onu AppWidgetManager vasitəsilə ötürür. Kliklərin işlənməsi — vidjet düymələr üçün PendingIntent-i dəstəkləyir: klikdən sonra Activity açılır və ya əmr yerinə yetirilir. Android 12-dən etibarən vidjetlər yuvarlaq künclər, Material You adaptiv rəngləri və dinamik ölçü dəyişmə dəstəyi aldı.
WidgetKit və SwiftUI istifadə edərək Swift-də hava vidjeti yaradaq. Layihə Xcode-da File → New → Target → Widget Extension vasitəsilə əlavə edilən Widget Extension target-i ehtiva etməlidir.
import WidgetKit
import SwiftUI
// 1. Vidjet üçün məlumat modeli
struct WeatherEntry: TimelineEntry {
let date: Date
let temperature: Int
let condition: String
}
// 2. TimelineProvider — məlumat təminatçısı
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), temperature: 22, condition: "Günəşli")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Günəşli")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let now = Date()
let entry = WeatherEntry(date: now, temperature: 20, condition: "Buludlu")
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
// 3. Göstərmək üçün SwiftUI View
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text("Hava").font(.caption).foregroundColor(.secondary)
HStack {
Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
Spacer()
Text(entry.condition).font(.body)
}
}.padding()
}
}
// 4. Vidjet konfiqurasiyası
@main
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
WeatherWidgetEntryView(entry: entry)
}
.configurationDisplayName("Hava")
.description("Cari temperaturu göstərir")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Əsas məqamlar: TimelineProvider hansı məlumatların və nə vaxt göstəriləcəyini müəyyən edir; getTimeline .after(nextUpdate) yeniləmə siyasəti ilə zaman şkalası yaradır; StaticConfiguration provayderi View ilə əlaqələndirir. Dinamik məlumatlar üçün istifadəçi parametrləri ilə IntentConfiguration istifadə olunur.
AppWidgetProvider və RemoteViews ilə Kotlin-də analoji hava vidjetini tətbiq edək.
// 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 = "Buludlu"
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 — provayderin qeydiyyatı
<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 faylı minimum ölçüləri, intervalı və layout-u müəyyən edir: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 saat). RemoteViews yalnız dəstəklənən komponentlərdən istifadə edir: LinearLayout, TextView, ImageView. Xüsusi View və ConstraintLayout Android 5.0-dan etibarən mövcuddur. GlanceLayout — RemoteViews üçün eksperimental Compose yanaşması — Android 15-də ortaya çıxdı.
Tez-tez verilən suallar
iOS WidgetKit üç sabit ölçü (small, medium, large) və sistem büdcəsi ilə TimelineProvider vasitəsilə yeniləmə təklif edir. Android AppWidgetProvider hüceyrələrdə elastik ölçülər, render üçün RemoteViews və updatePeriodMillis və ya WorkManager ilə yeniləmə istifadə edir.
iOS-da yeniləməni sistem idarə edir — minimum interval 15–30 dəqiqə, kritik məlumatlar üçün push-to-refresh istifadə olunur. Android-də interval updatePeriodMillis-də (minimum 30 dəqiqə) və ya fon tapşırıqları üçün WorkManager vasitəsilə təyin edilir.
iOS small (170x170pt), medium (360x170pt) və large (360x380pt) ölçülərini dəstəkləyir. Android elastik hüceyrə şəbəkəsindən istifadə edir: 2x1-dən 5x5-ə qədər, ölçü launçerdən və OS versiyasından asılıdır.
iOS-da vidjet daxilində animasiyalar yoxdur — bunlar statik elementlərdir. Android RemoteViews setFloat() və ViewPropertyAnimator vasitəsilə əsas animasiyaları dəstəkləyir, lakin mürəkkəb animasiyalar mövcud deyil.
Düzgün tətbiq edildikdə — yox. Sistem vidjet resurslarını ciddi şəkildə məhdudlaşdırır: iOS-da yeniləmə və yaddaş büdcəsi (30–50 MB), Android-də — minimum yeniləmə intervalı. Problematik vidjetlər sistem tərəfindən məcburi dayandırılır.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun