Widget est un élément d'interface utilisateur compact sur l'écran d'accueil iOS ou Android qui affiche des informations pertinentes sans ouvrir l'application. Les widgets sont apparus dans iOS 14 (2020) avec le framework WidgetKit sur SwiftUI et existent sur Android depuis la version 1.5 via AppWidgetProvider en Kotlin ou Java. Ils permettent à l'utilisateur de voir la météo, les taux de change, le calendrier, les notes ou l'état des tâches directement sur l'écran d'accueil, économisant du temps et simplifiant l'interaction. Selon Apple, les utilisateurs interagissent avec les widgets en moyenne 4 à 6 fois par jour, et placer un widget sur l'écran d'accueil augmente l'engagement dans l'application de 20 à 30 %. Pour Android, ces chiffres sont comparables. Voyons comment fonctionnent les widgets sur les deux plateformes avec des exemples de code.
Points clés
Widget est un élément d'interface utilisateur compact placé sur l'écran d'accueil d'un appareil mobile pour afficher des informations pertinentes d'une application. Contrairement à une application complète, un widget ne nécessite pas de lancement — l'utilisateur voit les données immédiatement après avoir déverrouillé l'écran. Le concept provient des systèmes d'exploitation de bureau (macOS Dashboard, Windows Sidebar), et dans l'environnement mobile, Android a introduit la prise en charge des widgets dès sa première version (Android 1.5 Cupcake, 2009), tandis qu'Apple ne les a ajoutés que dans iOS 14.
L'implémentation technique diffère selon les plateformes. Un widget iOS est une cible séparée dans Xcode, compilée en tant qu'extension de widget, fonctionnant dans son propre processus. Un widget Android est un BroadcastReceiver étendant AppWidgetProvider, rendant la mise en page via RemoteViews. Les deux plateformes imposent des restrictions strictes de performance et de mémoire : le système peut supprimer le widget si les limites sont dépassées. iOS limite les widgets à 30–50 Mo et le temps de génération du timeline à 10 secondes. Android — intervalle de mise à jour ne dépassant pas 30 minutes via updatePeriodMillis et arrêt forcé si onUpdate se bloque.
Smart Stack sur iOS et les piles sur Android permettent à l'utilisateur de regrouper plusieurs widgets dans un seul emplacement de l'écran d'accueil. L'appareil change automatiquement le widget affiché en fonction de l'heure, de l'emplacement ou de l'activité de l'utilisateur. Par exemple, le matin le calendrier s'affiche, pendant la journée — la météo, le soir — les notes. Pour les développeurs, cela signifie que le widget doit fonctionner correctement dans une pile et ne pas dépendre d'un affichage constant.
WidgetKit est le framework d'Apple pour créer des widgets sur iOS 14+, iPadOS 14+ et macOS 11+. Les widgets sont écrits en Swift utilisant SwiftUI et le mécanisme TimelineProvider pour la mise à jour du contenu. L'architecture WidgetKit comprend trois composants : TimelineProvider — une source de données qui forme une chronologie avec des entrées ; Widget Entry View — une vue SwiftUI qui affiche le contenu basé sur une entrée ; Widget Configuration — une description du type, des tailles et des familles du widget.
WidgetKit gère les mises à jour automatiquement — le développeur ne peut pas forcer une mise à jour du widget plus souvent que le système ne le permet. Apple utilise un budget de mises à jour distribué entre tous les widgets sur l'appareil. L'intervalle minimum est de 15 à 30 minutes. Pour les données critiques (par exemple, le statut de livraison), push-to-refresh est utilisé — envoi d'une notification push avec une date future pertinente, après quoi WidgetKit demande une nouvelle chronologie. À partir d'iOS 17, les widgets prennent en charge l'interactivité via App Intents — les utilisateurs peuvent appuyer sur des boutons à l'intérieur d'un widget sans ouvrir l'application.
| Taille | iOS (pt) | Contenu |
|---|---|---|
| Small | 170 × 170 | 1–2 indicateurs : température, taux de change |
| Medium | 360 × 170 | 2–4 indicateurs : prévisions à 5 jours, liste |
| Large | 360 × 380 | 5–10 indicateurs : calendrier, fil d'actualités |
AppWidgetProvider est la classe de base pour créer des widgets sur Android, faisant partie du SDK Android depuis API level 3. Un widget Android est un BroadcastReceiver qui reçoit les événements de mise à jour, d'activation et de désactivation du système. Contrairement à iOS, où le widget est rendu avec SwiftUI sur son propre moteur, Android utilise RemoteViews — un ensemble limité de composants View rendus dans le processus système (lanceur). Les vues personnalisées, les animations complexes ou les bibliothèques d'interface utilisateur ne peuvent pas être utilisées.
Le flux de travail du widget Android comprend quatre étapes. Configuration — lors de l'ajout d'un widget à l'écran, le système peut lancer une activité de configuration où l'utilisateur sélectionne les paramètres. Mise à jour — le système appelle onUpdate() à un intervalle défini (minimum 30 minutes) ou sur un signal de l'application via WorkManager. Rendu — le fournisseur crée RemoteViews avec les données actuelles et les transmet via AppWidgetManager. Gestion des touches — le widget prend en charge PendingIntent pour les boutons : un clic ouvre une activité ou effectue une action. À partir d'Android 12, les widgets ont obtenu la prise en charge des coins arrondis, des couleurs adaptatives Material You et du changement dynamique de taille.
Créons un widget météo en Swift utilisant WidgetKit et SwiftUI. Le projet doit inclure une cible d'extension de widget, ajoutée dans Xcode via Fichier → Nouveau → Cible → Extension de widget.
import WidgetKit
import SwiftUI
// 1. Modèle de données pour le widget
struct WeatherEntry: TimelineEntry {
let date: Date
let temperature: Int
let condition: String
}
// 2. TimelineProvider — fournisseur de données
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(), temperature: 22, condition: "Ensoleillé")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Ensoleillé")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let now = Date()
let entry = WeatherEntry(date: now, temperature: 20, condition: "Nuageux")
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
completion(timeline)
}
}
// 3. Vue SwiftUI pour l'affichage
struct WeatherWidgetEntryView: View {
var entry: WeatherEntry
var body: some View {
VStack(alignment: .leading) {
Text("Météo").font(.caption).foregroundColor(.secondary)
HStack {
Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
Spacer()
Text(entry.condition).font(.body)
}
}.padding()
}
}
// 4. Configuration du widget
@main
struct WeatherWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
WeatherWidgetEntryView(entry: entry)
}
.configurationDisplayName("Météo")
.description("Affiche la température actuelle")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
Points clés : TimelineProvider détermine quand et quelles données afficher ; getTimeline crée une chronologie avec la politique de mise à jour .after(nextUpdate) ; StaticConfiguration connecte le fournisseur à la vue. Pour les données dynamiques, IntentConfiguration est utilisé avec des paramètres personnalisés.
Implémentons un widget météo similaire en Kotlin avec AppWidgetProvider et 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 = "Nuageux"
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 — enregistrement du fournisseur
<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>
Le fichier widget_weather_info.xml définit les tailles minimales, l'intervalle et la mise en page : minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 heure). RemoteViews utilise uniquement les composants pris en charge : LinearLayout, TextView, ImageView. Les vues personnalisées et ConstraintLayout sont disponibles depuis Android 5.0. GlanceLayout — une approche expérimentale basée sur Compose pour RemoteViews — est apparue dans Android 15.
Questions fréquentes
iOS WidgetKit propose trois tailles fixes (small, medium, large) et une mise à jour via TimelineProvider avec un budget système. Android AppWidgetProvider utilise des tailles flexibles basées sur des cellules, RemoteViews pour le rendu et une mise à jour via updatePeriodMillis ou WorkManager.
Sur iOS, le système contrôle les mises à jour — l'intervalle minimum est de 15 à 30 minutes, pour les données critiques, push-to-refresh est utilisé. Sur Android, l'intervalle est défini dans updatePeriodMillis (minimum 30 minutes) ou via WorkManager pour les tâches en arrière-plan.
iOS prend en charge small (170x170pt), medium (360x170pt) et large (360x380pt). Android utilise une grille de cellules flexible : de 2x1 à 5x5, la taille dépend du lanceur et de la version du système d'exploitation.
Sur iOS, les animations à l'intérieur des widgets ne sont pas disponibles — ce sont des éléments statiques. Android RemoteViews prend en charge les animations de base via setFloat() et ViewPropertyAnimator, mais les animations complexes ne sont pas disponibles.
Avec une implémentation correcte — non. Le système limite strictement les ressources du widget : sur iOS — budget de mise à jour et de mémoire (30–50 Mo), sur Android — intervalle de mise à jour minimum. Les widgets problématiques sont terminés de force par le système.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi