Widget: What It Is, Widgets on iOS WidgetKit and Android

Author: IT Sectr Published: 2026-02-15 Reading time: 10 min

Widget is a compact user interface element on the iOS or Android home screen that displays relevant information without opening the app. Widgets appeared in iOS 14 (2020) with the WidgetKit framework on SwiftUI and have existed on Android since version 1.5 via AppWidgetProvider on Kotlin or Java. They allow users to see weather, exchange rates, calendar, notes or task status directly on the home screen, saving time and simplifying interaction. According to Apple, users interact with widgets on average 4–6 times a day, and placing a widget on the home screen increases app engagement by 20–30%. For Android, these metrics are comparable. Let's explore how widgets work on both platforms with code examples.

Key Takeaways

  • Widget — a mini-application on the home screen for quick information viewing without launching the main app
  • iOS WidgetKit (iOS 14+) is built on SwiftUI with three sizes and updates via TimelineProvider
  • Android AppWidgetProvider has existed since API level 3 and uses RemoteViews — a limited set of Views in a separate process
  • Data update on iOS — via timeline with date specifications, on Android — via updateIntervalMillis or WorkManager
  • Smart Stack on iOS and widget stacks on Android allow grouping multiple widgets into one slot

What is a Widget

Widget is a compact user interface element placed on the home screen of a mobile device to display relevant information from an app. Unlike a full application, a widget does not require launching — the user sees data immediately after unlocking the screen. The concept originated from desktop OS (macOS Dashboard, Windows Sidebar), and in the mobile environment, Android introduced widget support with its first release (Android 1.5 Cupcake, 2009), while Apple added them only in iOS 14.

Technical implementation differs across platforms. An iOS widget is a separate target in Xcode, compiled as a Widget Extension, running in its own process. An Android widget is a BroadcastReceiver extending AppWidgetProvider, rendering the layout via RemoteViews. Both platforms impose strict performance and memory restrictions: the system may remove the widget if limits are exceeded. iOS limits widgets to 30–50 MB and timeline generation time to 10 seconds. Android — update interval no more than 30 minutes via updatePeriodMillis and forced termination if onUpdate hangs.

Smart Stack on iOS and stacks on Android allow users to group multiple widgets into one home screen slot. The device automatically switches the displayed widget based on time of day, location, or user activity. For example, in the morning the calendar is shown, during the day — weather, in the evening — notes. For developers, this means the widget must work correctly as part of a stack and not rely on constant display.

iOS WidgetKit: SwiftUI and TimelineProvider

WidgetKit is Apple's framework for creating widgets on iOS 14+, iPadOS 14+, and macOS 11+. Widgets are written in Swift using SwiftUI and the TimelineProvider mechanism for content updates. The WidgetKit architecture includes three components: TimelineProvider — a data source that forms a timeline with entries; Widget Entry View — a SwiftUI View that displays content based on an entry; Widget Configuration — a description of the widget type, sizes, and families.

WidgetKit manages updates automatically — the developer cannot force a widget update more often than the system allows. Apple uses an update budget distributed among all widgets on the device. The minimum interval is 15–30 minutes. For critical data (e.g., delivery status), push-to-refresh is used — sending a push notification with a relevant future date, after which WidgetKit requests a new timeline. Starting from iOS 17, widgets support interactivity via App Intents — users can press buttons inside a widget without opening the app.

SizeiOS (pt)Content
Small170 × 1701–2 metrics: temperature, exchange rate
Medium360 × 1702–4 metrics: 5-day forecast, list
Large360 × 3805–10 metrics: calendar, news feed

Android AppWidgetProvider: RemoteViews

AppWidgetProvider is the base class for creating widgets on Android, part of the Android SDK since API level 3. An Android widget is a BroadcastReceiver that receives update, enable, and disable events from the system. Unlike iOS, where the widget is rendered with SwiftUI on its own engine, Android uses RemoteViews — a limited set of View components rendered in the system process (launcher). Custom Views, complex animations, or UI libraries cannot be used.

The Android widget workflow includes four stages. Configuration — when adding a widget to the screen, the system may launch a configuration Activity where the user selects settings. Update — the system calls onUpdate() at a specified interval (minimum 30 minutes) or upon a signal from the app via WorkManager. Rendering — the provider creates RemoteViews with current data and passes them through AppWidgetManager. Touch handling — the widget supports PendingIntent for buttons: clicking opens an Activity or performs an action. Starting from Android 12, widgets gained support for rounded corners, adaptive Material You colors, and dynamic size changes.

Creating a Widget on iOS with WidgetKit

Let's create a weather widget in Swift using WidgetKit and SwiftUI. The project must include a Widget Extension target, added in Xcode via File → New → Target → Widget Extension.

swift
import WidgetKit
import SwiftUI

// 1. Data model for the widget
struct WeatherEntry: TimelineEntry {
    let date: Date
    let temperature: Int
    let condition: String
}

// 2. TimelineProvider — data provider
struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> WeatherEntry {
        WeatherEntry(date: Date(), temperature: 22, condition: "Sunny")
    }

    func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
        let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Sunny")
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
        let now = Date()
        let entry = WeatherEntry(date: now, temperature: 20, condition: "Cloudy")
        let nextUpdate = Calendar.current.date(byAdding: .hour, value: 3, to: now)!
        let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
        completion(timeline)
    }
}

// 3. SwiftUI View for display
struct WeatherWidgetEntryView: View {
    var entry: WeatherEntry

    var body: some View {
        VStack(alignment: .leading) {
            Text("Weather").font(.caption).foregroundColor(.secondary)
            HStack {
                Text("\(entry.temperature)°").font(.largeTitle).fontWeight(.bold)
                Spacer()
                Text(entry.condition).font(.body)
            }
        }.padding()
    }
}

// 4. Widget configuration
@main
struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
            WeatherWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Weather")
        .description("Shows the current temperature")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

Key points: TimelineProvider determines when and what data to show; getTimeline creates a timeline with the .after(nextUpdate) update policy; StaticConfiguration connects the provider to the View. For dynamic data, IntentConfiguration is used with custom parameters.

Creating a Widget on Android with AppWidgetProvider

Let's implement a similar weather widget in Kotlin with AppWidgetProvider and RemoteViews.

kotlin
// 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 = "Cloudy"
            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 — provider registration
<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>

The widget_weather_info.xml file sets minimum sizes, interval, and layout: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 hour). RemoteViews uses only supported components: LinearLayout, TextView, ImageView. Custom Views and ConstraintLayout are available since Android 5.0. GlanceLayout — an experimental Compose-based approach for RemoteViews — appeared in Android 15.

Frequently Asked Questions

What is the difference between Widget on iOS and Android?

iOS WidgetKit offers three fixed sizes (small, medium, large) and updates via TimelineProvider with a system budget. Android AppWidgetProvider uses flexible cell-based sizes, RemoteViews for rendering, and updates via updatePeriodMillis or WorkManager.

How often does a Widget update?

On iOS, the system controls updates — the minimum interval is 15–30 minutes, for critical data push-to-refresh is used. On Android, the interval is set in updatePeriodMillis (minimum 30 minutes) or via WorkManager for background tasks.

What sizes does Widget support?

iOS supports small (170x170pt), medium (360x170pt), and large (360x380pt). Android uses a flexible cell grid: from 2x1 to 5x5, size depends on the launcher and OS version.

Can I add animation to a Widget?

On iOS, animations inside widgets are not available — they are static elements. Android RemoteViews supports basic animations via setFloat() and ViewPropertyAnimator, but complex animations are not available.

Does a Widget reduce device performance?

With proper implementation — no. The system strictly limits widget resources: on iOS — update and memory budget (30–50 MB), on Android — minimum update interval. Problematic widgets are forcibly terminated by the system.

Summary

  • Widget — a compact home screen element for quick access to app data without opening it
  • iOS WidgetKit supports three fixed sizes and updates via TimelineProvider with SwiftUI
  • Android AppWidgetProvider works via BroadcastReceiver and RemoteViews with flexible cell sizes
  • Data update on both platforms is system-limited: iOS — update budget, Android — minimum 30 minutes
  • Interactivity appeared on iOS 17 (App Intents) and Android 12 (dynamic colors, buttons)
  • Smart Stack on iOS and stacks on Android allow grouping multiple widgets with auto-switching
  • Performance is critical — the system forcibly terminates problematic widgets when limits are exceeded

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also