Widget — ett kompakt användargränssnittselement på hemskärmen för iOS eller Android som visar aktuell information utan att öppna appen. Widgetar dök upp i iOS 14 (2020) med WidgetKit-ramverket i SwiftUI och finns i Android sedan version 1.5 via AppWidgetProvider i Kotlin eller Java. De låter användaren se väder, valutakurser, kalender, anteckningar eller uppgiftsstatus direkt på home screen, vilket sparar tid och förenklar interaktionen. Enligt Apple-data interagerar användare med widgetar i genomsnitt 4–6 gånger om dagen, och att placera en widget på home screen ökar engagemanget i appen med 20–30%. För Android är dessa siffror jämförbara. Låt oss undersöka hur widgetar fungerar på båda plattformarna, med kodexempel.
Huvudpunkter
Widget — är ett kompakt användargränssnittselement som placeras på hemskärmen på en mobil enhet för att visa aktuell information från appen. Till skillnad från en full app kräver en widget ingen start — användaren ser data direkt efter upplåsning av skärmen. Konceptet kommer från stationära operativsystem (macOS Dashboard, Windows Sidebar), och i mobilmiljön introducerade Android stöd för widgetar från sin första version (Android 1.5 Cupcake, 2009), medan Apple lade till dem först i iOS 14.
Teknisk implementering skiljer sig mellan plattformarna. iOS-widget — en separat target i Xcode, kompilerad som Widget Extension, som körs i egen process. Android-widget — en BroadcastReceiver som utökar AppWidgetProvider och renderar layouten via RemoteViews. Båda plattformarna inför strikta begränsningar för prestanda och minne: systemet kan ta bort widgeten vid överskridande av gränser. iOS begränsar widgeten till 30–50 MB och tiden för att skapa timeline till 10 sekunder. Android — uppdateringsintervall inte oftare än 30 minuter via updatePeriodMillis och tvångsavslutning vid hängning av onUpdate.
Smart Stack på iOS och staplar på Android låter användaren gruppera flera widgetar i en plats på home screen. Enheten växlar automatiskt den visade widgeten beroende på tid på dagen, plats eller användaraktivitet. På morgonen visas till exempel kalendern, på dagen — vädret, på kvällen — anteckningar. För utvecklaren innebär detta att widgeten måste fungera korrekt i en stack och inte förlita sig på konstant visning.
WidgetKit — Apples ramverk för att skapa widgetar på iOS 14+, iPadOS 14+ och macOS 11+. Widgetar skrivs i Swift med SwiftUI och TimelineProvider-mekanismen för att uppdatera innehåll. WidgetKit-arkitekturen innehåller tre komponenter: TimelineProvider — datakälla som bildar en tidslinje med poster; Widget Entry View — SwiftUI View som visar innehåll baserat på en post; Widget Configuration — beskrivning av typ, storlekar och familjer för widgeten.
WidgetKit hanterar själv uppdateringen — utvecklaren kan inte tvinga widgeten att uppdateras oftare än systemet tillåter. Apple använder en uppdateringsbudget som fördelas mellan alla widgetar på enheten. Minsta intervall — 15–30 minuter. För kritisk data (t.ex. leveransstatus) används push-to-refresh — att skicka ett push-meddelande med ett relevant datum i framtiden, varefter WidgetKit begär en ny tidslinje. Från och med iOS 17 stöder widgetar interaktivitet via App Intents — användaren kan trycka på knappar inuti widgeten utan att öppna appen.
| Storlek | iOS (pt) | Innehåll |
|---|---|---|
| Small | 170 × 170 | 1–2 indikatorer: temperatur, valutakurs |
| Medium | 360 × 170 | 2–4 indikatorer: 5-dagarsprognos, lista |
| Large | 360 × 380 | 5–10 indikatorer: kalender, nyhetsflöde |
AppWidgetProvider — basklassen för att skapa widgetar i Android, en del av Android SDK sedan API level 3. Android-widget — är en BroadcastReceiver som tar emot uppdaterings-, aktiverings- och avaktiveringshändelser från systemet. Till skillnad från iOS, där widgeten ritas av SwiftUI på egen motor, använder Android RemoteViews — en begränsad uppsättning View-komponenter som renderas i systemprocessen (launcher). Anpassade View, komplexa animationer eller UI-bibliotek kan inte användas.
Arbetschema för Android-widget omfattar fyra steg. Konfiguration — när widgeten läggs till på skärmen kan systemet starta en konfigurations-Activity där användaren väljer inställningar. Uppdatering — systemet anropar onUpdate() med ett angivet intervall (minst 30 minuter) eller på signal från appen via WorkManager. Rendering — leverantören skapar RemoteViews med aktuell data och överför dem via AppWidgetManager. Hantering av klick — widgeten stöder PendingIntent för knappar: vid klick öppnas en Activity eller en åtgärd utförs. Från och med Android 12 fick widgetar stöd för rundade hörn, adaptiva Material You-färger och dynamisk storleksändring.
Låt oss skapa en väderwidget i Swift med WidgetKit och SwiftUI. Projektet ska innehålla ett Widget Extension target, som läggs till i Xcode via File → New → Target → Widget Extension.
import WidgetKit
import SwiftUI
// 1. Datamodell för widget
struct WeatherEntry: TimelineEntry {
let date: Date
let temperature: Int
let condition: String
}
// 2. TimelineProvider — dataleverantör
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), temperature: 22, condition: "Soligt")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Soligt")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let now = Date()
let entry = WeatherEntry(date: now, temperature: 20, condition: "Molnigt")
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
// 3. SwiftUI View för visning
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text("Väder").font(.caption).foregroundColor(.secondary)
HStack {
Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
Spacer()
Text(entry.condition).font(.body)
}
}.padding()
}
}
// 4. Widgetkonfiguration
@main
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
WeatherWidgetEntryView(entry: entry)
}
.configurationDisplayName("Väder")
.description("Visar aktuell temperatur")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Viktiga punkter: TimelineProvider bestämmer när och vilken data som ska visas; getTimeline skapar en tidslinje med uppdateringspolicy .after(nextUpdate); StaticConfiguration kopplar leverantören till View. För dynamisk data används IntentConfiguration med användarparametrar.
Vi implementerar en liknande väderwidget i Kotlin med AppWidgetProvider och 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 = "Molnigt"
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 — registrering av leverantör
<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>
Filwidget_weather_info.xml anger minsta storlekar, intervall och layout: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 timme). RemoteViews använder endast komponenter som stöds: LinearLayout, TextView, ImageView. Anpassade View och ConstraintLayout är tillgängliga sedan Android 5.0. GlanceLayout — experimentell Compose-metod för RemoteViews — dök upp i Android 15.
Vanliga frågor
iOS WidgetKit erbjuder tre fasta storlekar (small, medium, large) och uppdatering via TimelineProvider med systembudget. Android AppWidgetProvider använder flexibla storlekar i celler, RemoteViews för rendering och uppdatering via updatePeriodMillis eller WorkManager.
På iOS styrs uppdateringen av systemet — minsta intervall 15–30 minuter, för kritisk data används push-to-refresh. På Android ställs intervallet in i updatePeriodMillis (minst 30 minuter) eller via WorkManager för bakgrundsuppgifter.
iOS stöder small (170x170pt), medium (360x170pt) och large (360x380pt). Android använder ett flexibelt cellrutnät: från 2x1 till 5x5, storleken beror på startprogrammet och OS-versionen.
På iOS finns inga animationer inuti widgeten — de är statiska element. Android RemoteViews stöder grundläggande animationer via setFloat() och ViewPropertyAnimator, men komplexa animationer är inte tillgängliga.
Vid korrekt implementering — nej. Systemet begränsar strikt widgetens resurser: på iOS uppdaterings- och minnesbudget (30–50 MB), på Android — minsta uppdateringsintervall. Problemwidgetar tvångsavslutas av systemet.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också