Widget — kompaktní prvek uživatelského rozhraní na domovské obrazovce iOS nebo Android, který zobrazuje aktuální informace bez otevření aplikace. Widgety se objevily v iOS 14 (2020) s frameworkem WidgetKit v SwiftUI a existují v Android od verze 1.5 přes AppWidgetProvider v Kotlin nebo Java. Umožňují uživateli vidět počasí, kurz měn, kalendář, poznámky nebo stav úkolů přímo na home screen, šetří čas a zjednodušují interakci. Podle údajů Apple uživatelé interagují s widgety v průměru 4–6krát denně a instalace widgetu na home screen zvyšuje zapojení do aplikace o 20–30%. Pro Android jsou tato čísla srovnatelná. Pojďme se podívat, jak widgety fungují na obou platformách, s příklady kódu.
Hlavní body
Widget — je kompaktní prvek uživatelského rozhraní umístěný na domovské obrazovce mobilního zařízení pro zobrazení aktuálních informací z aplikace. Na rozdíl od plné aplikace widget nevyžaduje spuštění — uživatel vidí data ihned po odemknutí obrazovky. Koncept pochází z desktopových OS (macOS Dashboard, Windows Sidebar) a v mobilním prostředí Android zavedl podporu widgetů od svého prvního vydání (Android 1.5 Cupcake, 2009), zatímco Apple je přidal až v iOS 14.
Technická implementace se liší na platformách. iOS widget — samostatný target v Xcode, kompilovaný jako Widget Extension, běžící ve vlastním procesu. Android widget — BroadcastReceiver rozšiřující AppWidgetProvider, vykreslující rozvržení přes RemoteViews. Obě platformy ukládají přísná omezení na výkon a paměť: systém může widget odstranit při překročení limitů. iOS omezuje widget na 30–50 MB a čas vytvoření timeline na 10 sekund. Android — interval aktualizace ne častěji než 30 minut přes updatePeriodMillis a vynucené ukončení při zamrznutí onUpdate.
Smart Stack na iOS a hromádky na Android umožňují uživateli seskupit více widgetů do jednoho slotu na home screen. Zařízení automaticky přepíná zobrazený widget v závislosti na denní době, poloze nebo aktivitě uživatele. Například ráno se zobrazí kalendář, přes den — počasí, večer — poznámky. Pro vývojáře to znamená, že widget musí správně fungovat v rámci hromádky a nespoléhat se na trvalé zobrazení.
WidgetKit — framework Apple pro vytváření widgetů na iOS 14+, iPadOS 14+ a macOS 11+. Widgety se píší ve Swift pomocí SwiftUI a mechanismu TimelineProvider pro aktualizaci obsahu. Architektura WidgetKit zahrnuje tři komponenty: TimelineProvider — zdroj dat, který tvoří časovou osu se záznamy; Widget Entry View — SwiftUI View zobrazující obsah na základě záznamu; Widget Configuration — popis typu, velikostí a rodin widgetu.
WidgetKit sám spravuje aktualizaci — vývojář nemůže vynutit aktualizaci widgetu častěji, než systém povoluje. Apple používá rozpočet aktualizací rozdělovaný mezi všechny widgety na zařízení. Minimální interval — 15–30 minut. Pro kritická data (např. stav doručení) se používá push-to-refresh — odeslání push oznámení s relevantním datem v budoucnosti, po kterém WidgetKit požádá o novou časovou osu. Od iOS 17 widgety podporují interaktivitu přes App Intents — uživatel může mačkat tlačítka uvnitř widgetu bez otevření aplikace.
| Velikost | iOS (pt) | Obsah |
|---|---|---|
| Small | 170 × 170 | 1–2 ukazatele: teplota, kurz měny |
| Medium | 360 × 170 | 2–4 ukazatele: předpověď na 5 dní, seznam |
| Large | 360 × 380 | 5–10 ukazatelů: kalendář, zpravodajský kanál |
AppWidgetProvider — základní třída pro vytváření widgetů v Android, součást Android SDK od API level 3. Android widget — je BroadcastReceiver přijímající události aktualizace, aktivace a deaktivace od systému. Na rozdíl od iOS, kde widget kreslí SwiftUI na vlastním enginu, Android používá RemoteViews — omezenou sadu komponent View vykreslovaných v systémovém procesu (launcher). Nelze použít vlastní View, složité animace nebo UI knihovny.
Schéma fungování Android widgetu zahrnuje čtyři fáze. Konfigurace — při přidávání widgetu na obrazovku může systém spustit konfigurační Activity, kde uživatel volí nastavení. Aktualizace — systém volá onUpdate() v nastaveném intervalu (minimálně 30 minut) nebo na signál z aplikace přes WorkManager. Vykreslení — poskytovatel vytvoří RemoteViews s aktuálními daty a předá je přes AppWidgetManager. Zpracování kliknutí — widget podporuje PendingIntent pro tlačítka: po kliknutí se otevře Activity nebo se provede akce. Od Android 12 widgety získaly podporu pro zaoblené rohy, adaptivní barvy Material You a dynamickou změnu velikosti.
Vytvořme widget počasí ve Swift pomocí WidgetKit a SwiftUI. Projekt by měl obsahovat Widget Extension target, přidaný v Xcode přes File → New → Target → Widget Extension.
import WidgetKit
import SwiftUI
// 1. Datový model pro widget
struct WeatherEntry: TimelineEntry {
let date: Date
let temperature: Int
let condition: String
}
// 2. TimelineProvider — poskytovatel dat
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), temperature: 22, condition: "Slunečno")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Slunečno")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let now = Date()
let entry = WeatherEntry(date: now, temperature: 20, condition: "Zataženo")
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
// 3. SwiftUI View pro zobrazení
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text("Počasí").font(.caption).foregroundColor(.secondary)
HStack {
Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
Spacer()
Text(entry.condition).font(.body)
}
}.padding()
}
}
// 4. Konfigurace widgetu
@main
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
WeatherWidgetEntryView(entry: entry)
}
.configurationDisplayName("Počasí")
.description("Zobrazuje aktuální teplotu")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Klíčové body: TimelineProvider určuje, kdy a jaká data zobrazit; getTimeline vytváří časovou osu s politikou aktualizace .after(nextUpdate); StaticConfiguration propojuje poskytovatele s View. Pro dynamická data se používá IntentConfiguration s uživatelskými parametry.
Implementujeme podobný widget počasí v Kotlin s AppWidgetProvider a RemoteViews.
// 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 = "Zataženo"
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 — registrace poskytovatele
<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>
Soubor widget_weather_info.xml nastavuje minimální velikosti, interval a rozvržení: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 hodina). RemoteViews používá pouze podporované komponenty: LinearLayout, TextView, ImageView. Vlastní View a ConstraintLayout jsou dostupné od Android 5.0. GlanceLayout — experimentální přístup Compose pro RemoteViews — se objevil v Android 15.
Často kladené otázky
iOS WidgetKit nabízí tři pevné velikosti (small, medium, large) a aktualizaci přes TimelineProvider s rozpočtem systému. Android AppWidgetProvider používá flexibilní velikosti v buňkách, RemoteViews pro vykreslení a aktualizaci přes updatePeriodMillis nebo WorkManager.
Na iOS aktualizaci řídí systém — minimální interval 15–30 minut, pro kritická data se používá push-to-refresh. Na Android je interval nastaven v updatePeriodMillis (minimálně 30 minut) nebo přes WorkManager pro úlohy na pozadí.
iOS podporuje small (170x170pt), medium (360x170pt) a large (360x380pt). Android používá flexibilní mřížku buněk: od 2x1 do 5x5, velikost závisí na spouštěči a verzi OS.
Na iOS uvnitř widgetu nejsou animace — jedná se o statické prvky. Android RemoteViews podporuje základní animace přes setFloat() a ViewPropertyAnimator, ale složité animace nejsou dostupné.
Při správné implementaci — ne. Systém striktně omezuje zdroje widgetu: na iOS rozpočet aktualizací a paměti (30–50 MB), na Android — minimální interval aktualizace. Problémové widgety systém vynuceně ukončí.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také