Widget è un elemento compatto dell'interfaccia utente sulla schermata home di iOS o Android che mostra informazioni rilevanti senza aprire l'app. I widget sono apparsi in iOS 14 (2020) con il framework WidgetKit su SwiftUI e esistono su Android dalla versione 1.5 tramite AppWidgetProvider in Kotlin o Java. Consentono all'utente di vedere meteo, tassi di cambio, calendario, note o stato delle attività direttamente sulla schermata home, risparmiando tempo e semplificando l'interazione. Secondo Apple, gli utenti interagiscono con i widget in media 4–6 volte al giorno e posizionare un widget sulla schermata home aumenta il coinvolgimento nell'app del 20–30%. Per Android, questi numeri sono comparabili. Analizziamo come funzionano i widget su entrambe le piattaforme con esempi di codice.
Punti chiave
Widget è un elemento compatto dell'interfaccia utente posizionato sulla schermata home di un dispositivo mobile per mostrare informazioni rilevanti da un'app. A differenza di un'applicazione completa, un widget non richiede avvio — l'utente vede i dati immediatamente dopo aver sbloccato lo schermo. Il concetto proviene dai sistemi operativi desktop (macOS Dashboard, Windows Sidebar) e nell'ambiente mobile, Android ha introdotto il supporto dei widget con la sua prima versione (Android 1.5 Cupcake, 2009), mentre Apple li ha aggiunti solo in iOS 14.
L'implementazione tecnica differisce tra le piattaforme. Un widget iOS è un target separato in Xcode, compilato come Widget Extension, che esegue nel proprio processo. Un widget Android è un BroadcastReceiver che estende AppWidgetProvider, renderizzando il layout tramite RemoteViews. Entrambe le piattaforme impongono restrizioni severe su prestazioni e memoria: il sistema può rimuovere il widget se i limiti vengono superati. iOS limita i widget a 30–50 MB e il tempo di generazione del timeline a 10 secondi. Android — intervallo di aggiornamento non superiore a 30 minuti tramite updatePeriodMillis e terminazione forzata se onUpdate si blocca.
Smart Stack su iOS e pile su Android consentono all'utente di raggruppare più widget in un unico slot della schermata home. Il dispositivo cambia automaticamente il widget visualizzato in base all'ora del giorno, alla posizione o all'attività dell'utente. Ad esempio, al mattino viene mostrato il calendario, durante il giorno — il meteo, alla sera — le note. Per gli sviluppatori, ciò significa che il widget deve funzionare correttamente come parte di una pila e non dipendere dalla visualizzazione costante.
WidgetKit è il framework di Apple per creare widget su iOS 14+, iPadOS 14+ e macOS 11+. I widget sono scritti in Swift utilizzando SwiftUI e il meccanismo TimelineProvider per l'aggiornamento dei contenuti. L'architettura WidgetKit include tre componenti: TimelineProvider — una fonte di dati che forma una timeline con voci; Widget Entry View — una SwiftUI View che mostra il contenuto basato su una voce; Widget Configuration — una descrizione del tipo, delle dimensioni e delle famiglie del widget.
WidgetKit gestisce gli aggiornamenti automaticamente — lo sviluppatore non può forzare un aggiornamento del widget più spesso di quanto il sistema consenta. Apple utilizza un budget di aggiornamento distribuito tra tutti i widget presenti sul dispositivo. L'intervallo minimo è di 15–30 minuti. Per i dati critici (ad esempio, stato della consegna), viene utilizzato push-to-refresh — invio di una notifica push con una data futura pertinente, dopo la quale WidgetKit richiede una nuova timeline. Da iOS 17, i widget supportano l'interattività tramite App Intents — gli utenti possono premere pulsanti all'interno di un widget senza aprire l'app.
| Dimensione | iOS (pt) | Contenuto |
|---|---|---|
| Small | 170 × 170 | 1–2 indicatori: temperatura, tasso di cambio |
| Medium | 360 × 170 | 2–4 indicatori: previsioni 5 giorni, elenco |
| Large | 360 × 380 | 5–10 indicatori: calendario, feed notizie |
AppWidgetProvider è la classe base per creare widget su Android, parte dell'Android SDK da API level 3. Un widget Android è un BroadcastReceiver che riceve eventi di aggiornamento, attivazione e disattivazione dal sistema. A differenza di iOS, dove il widget viene renderizzato con SwiftUI sul proprio motore, Android utilizza RemoteViews — un insieme limitato di componenti View renderizzati nel processo di sistema (launcher). Non possono essere utilizzate View personalizzate, animazioni complesse o librerie UI.
Il flusso di lavoro del widget Android include quattro fasi. Configurazione — quando si aggiunge un widget allo schermo, il sistema può avviare un'Activity di configurazione in cui l'utente seleziona le impostazioni. Aggiornamento — il sistema chiama onUpdate() a un intervallo definito (minimo 30 minuti) o su segnale dall'app tramite WorkManager. Renderizzazione — il provider crea RemoteViews con dati correnti e li passa tramite AppWidgetManager. Gestione tocchi — il widget supporta PendingIntent per i pulsanti: un clic apre un'Activity o esegue un'azione. Da Android 12, i widget hanno ottenuto supporto per angoli arrotondati, colori adattivi Material You e modifica dinamica delle dimensioni.
Creiamo un widget meteorologico in Swift usando WidgetKit e SwiftUI. Il progetto deve includere un target Widget Extension, aggiunto in Xcode tramite File → Nuovo → Target → Widget Extension.
import WidgetKit
import SwiftUI
// 1. Modello dati per il widget
struct WeatherEntry: TimelineEntry {
let date: Date
let temperature: Int
let condition: String
}
// 2. TimelineProvider — fornitore di dati
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), temperature: 22, condition: "Soleggiato")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Soleggiato")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let now = Date()
let entry = WeatherEntry(date: now, temperature: 20, condition: "Nuvoloso")
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
// 3. SwiftUI View per la visualizzazione
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text("Meteo").font(.caption).foregroundColor(.secondary)
HStack {
Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
Spacer()
Text(entry.condition).font(.body)
}
}.padding()
}
}
// 4. Configurazione del widget
@main
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
WeatherWidgetEntryView(entry: entry)
}
.configurationDisplayName("Meteo")
.description("Mostra la temperatura attuale")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Punti chiave: TimelineProvider determina quando e quali dati mostrare; getTimeline crea una timeline con la politica di aggiornamento .after(nextUpdate); StaticConfiguration collega il provider alla View. Per i dati dinamici, viene utilizzato IntentConfiguration con parametri personalizzati.
Implementiamo un widget meteorologico simile in Kotlin con AppWidgetProvider e 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 = "Nuvoloso"
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 — registrazione del fornitore
<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>
Il file widget_weather_info.xml imposta dimensioni minime, intervallo e layout: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 ora). RemoteViews utilizza solo componenti supportati: LinearLayout, TextView, ImageView. View personalizzate e ConstraintLayout sono disponibili da Android 5.0. GlanceLayout — un approccio sperimentale basato su Compose per RemoteViews — è apparso in Android 15.
Domande frequenti
iOS WidgetKit offre tre dimensioni fisse (small, medium, large) e aggiornamento tramite TimelineProvider con budget di sistema. Android AppWidgetProvider utilizza dimensioni flessibili basate su celle, RemoteViews per il rendering e aggiornamento tramite updatePeriodMillis o WorkManager.
Su iOS, il sistema controlla gli aggiornamenti — l'intervallo minimo è di 15–30 minuti, per i dati critici viene utilizzato push-to-refresh. Su Android, l'intervallo viene impostato in updatePeriodMillis (minimo 30 minuti) o tramite WorkManager per attività in background.
iOS supporta small (170x170pt), medium (360x170pt) e large (360x380pt). Android utilizza una griglia di celle flessibile: da 2x1 a 5x5, la dimensione dipende dal launcher e dalla versione del sistema operativo.
Su iOS, le animazioni all'interno dei widget non sono disponibili — sono elementi statici. Android RemoteViews supporta animazioni di base tramite setFloat() e ViewPropertyAnimator, ma le animazioni complesse non sono disponibili.
Con un'implementazione corretta — no. Il sistema limita rigorosamente le risorse del widget: su iOS — budget di aggiornamento e memoria (30–50 MB), su Android — intervallo di aggiornamento minimo. I widget problematici vengono terminati forzatamente dal sistema.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche