Widget: что это, виджеты на iOS WidgetKit и Android

Автор: IT Sectr Опубликовано: 2026-02-15 Время чтения: 10 мин

Widget — компактный элемент пользовательского интерфейса на домашнем экране iOS или Android, отображающий актуальную информацию без открытия приложения. Виджеты появились в iOS 14 (2020) с фреймворком WidgetKit на SwiftUI и существуют в Android с версии 1.5 через AppWidgetProvider на Kotlin или Java. Они позволяют пользователю видеть погоду, курс валют, календарь, заметки или статус задач прямо на home screen, экономя время и упрощая взаимодействие. По данным Apple, пользователи взаимодействуют с виджетами в среднем 4–6 раз в день, а установка виджета на home screen увеличивает вовлечённость в приложение на 20–30%. Для Android эти показатели сопоставимы. Разберём, как устроены виджеты на обеих платформах, с примерами кода.

Главное

  • Widget — мини-приложение на домашнем экране для быстрого просмотра информации без запуска основного приложения
  • iOS WidgetKit (iOS 14+) построен на SwiftUI с тремя размерами и обновлением через TimelineProvider
  • Android AppWidgetProvider существует с API level 3 и использует RemoteViews — ограниченный набор View в отдельном процессе
  • Обновление данных на iOS — через timeline с указанием дат, на Android — через updateIntervalMillis или WorkManager
  • Smart Stack на iOS и стопки виджетов на Android позволяют группировать несколько виджетов в один слот

Что такое Widget

Widget — это компактный элемент пользовательского интерфейса, размещаемый на домашнем экране мобильного устройства для отображения актуальной информации из приложения. В отличие от полноценного приложения, виджет не требует запуска — пользователь видит данные сразу после разблокировки экрана. Концепция пришла из десктопных ОС (macOS Dashboard, Windows Sidebar), а в мобильной среде Android ввёл поддержку виджетов с первого релиза (Android 1.5 Cupcake, 2009), тогда как Apple добавила их только в iOS 14.

Техническая реализация различается на платформах. Виджет iOS — отдельный target в Xcode, компилируемый как Widget Extension, работающий в собственном процессе. Виджет Android — BroadcastReceiver, расширяющий AppWidgetProvider, рендерящий макет через RemoteViews. Обе платформы накладывают строгие ограничения на производительность и память: система может удалить виджет при превышении лимитов. iOS ограничивает виджет 30–50 МБ и временем формирования timeline до 10 секунд. Android — интервал обновления не чаще 30 минут через updatePeriodMillis и принудительное завершение при зависании onUpdate.

Smart Stack на iOS и стопки на Android позволяют пользователю группировать несколько виджетов в один слот на home screen. Устройство автоматически переключает отображаемый виджет в зависимости от времени суток, местоположения или активности пользователя. Например, утром показывается календарь, днём — погода, вечером — заметки. Для разработчика это означает, что виджет должен корректно работать в составе стопки и не полагаться на постоянное отображение.

iOS WidgetKit: SwiftUI и TimelineProvider

WidgetKit — фреймворк Apple для создания виджетов на iOS 14+, iPadOS 14+ и macOS 11+. Виджеты пишутся на Swift с использованием SwiftUI и механизма TimelineProvider для обновления контента. Архитектура WidgetKit включает три компонента: TimelineProvider — источник данных, формирующий временную шкалу с записями; Widget Entry View — SwiftUI View, отображающая содержимое на основе записи; Widget Configuration — описание типа, размеров и семейств виджета.

WidgetKit сам управляет обновлением — разработчик не может принудительно обновить виджет чаще, чем позволяет система. Apple использует бюджет обновлений, распределяемый между всеми виджетами на устройстве. Минимальный интервал — 15–30 минут. Для критичных данных (например, статус доставки) используется push-to-refresh — отправка push-уведомления с релевантной датой в будущем, после которого WidgetKit запрашивает новый timeline. Начиная с iOS 17 виджеты поддерживают интерактивность через App Intents — пользователь может нажимать кнопки внутри виджета без открытия приложения.

РазмерiOS (pt)Контент
Small170 × 1701–2 показателя: температура, курс валюты
Medium360 × 1702–4 показателя: прогноз на 5 дней, список
Large360 × 3805–10 показателей: календарь, лента новостей

Android AppWidgetProvider: RemoteViews

AppWidgetProvider — базовый класс для создания виджетов на Android, входящий в состав Android SDK с API level 3. Виджет Android — это BroadcastReceiver, получающий события обновления, включения и отключения от системы. В отличие от iOS, где виджет рисуется SwiftUI на собственном движке, Android использует RemoteViews — ограниченный набор компонентов View, рендерящихся в процессе системы (launcher). Нельзя использовать кастомные View, сложные анимации или UI-библиотеки.

Схема работы Android-виджета включает четыре этапа. Конфигурация — при добавлении виджета на экран система может запустить Activity конфигурации, где пользователь выбирает настройки. Обновление — система вызывает onUpdate() через заданный интервал (минимум 30 минут) или по сигналу из приложения через WorkManager. Рендеринг — провайдер создаёт RemoteViews с актуальными данными и передаёт их через AppWidgetManager. Обработка нажатий — виджет поддерживает PendingIntent для кнопок: при клике открывается Activity или выполняется действие. Начиная с Android 12 виджеты получили поддержку закруглённых углов, адаптивных цветов Material You и динамического изменения размера.

Создание виджета на iOS с WidgetKit

Создадим виджет погоды на Swift с использованием WidgetKit и SwiftUI. Проект должен содержать Widget Extension target, добавляемый в Xcode через File → New → Target → Widget Extension.

swift
import WidgetKit
import SwiftUI

// 1. Модель данных для виджета
struct WeatherEntry: TimelineEntry {
    let date: Date
    let temperature: Int
    let condition: String
}

// 2. TimelineProvider — поставщик данных
struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> WeatherEntry {
        WeatherEntry(date: Date(), temperature: 22, condition: "Солнечно")
    }

    func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
        let entry = WeatherEntry(date: Date(), temperature: 22, condition: "Солнечно")
        completion(entry)
    }

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

// 3. SwiftUI View для отображения
struct WeatherWidgetEntryView: View {
    var entry: WeatherEntry

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

// 4. Конфигурация виджета
@main
struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
            WeatherWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Погода")
        .description("Показывает текущую температуру")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

Ключевые моменты: TimelineProvider определяет, когда и какие данные показывать; getTimeline создаёт временную шкалу с политикой обновления .after(nextUpdate); StaticConfiguration связывает провайдера с View. Для динамических данных используется IntentConfiguration с пользовательскими параметрами.

Создание виджета на Android с AppWidgetProvider

Реализуем аналогичный виджет погоды на Kotlin с AppWidgetProvider и 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 = "Облачно"
            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 — регистрация провайдера
<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>

Файл widget_weather_info.xml задаёт минимальные размеры, интервал и layout: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 час). RemoteViews использует только поддерживаемые компоненты: LinearLayout, TextView, ImageView. Кастомные View и ConstraintLayout доступны с Android 5.0. GlanceLayout — экспериментальный Compose-подход для RemoteViews — появился в Android 15.

Часто задаваемые вопросы

В чём разница между Widget на iOS и Android?

iOS WidgetKit предлагает три фиксированных размера (small, medium, large) и обновление через TimelineProvider с бюджетом системы. Android AppWidgetProvider использует гибкие размеры в ячейках, RemoteViews для рендеринга и обновление через updatePeriodMillis или WorkManager.

Как часто обновляется Widget?

На iOS обновление контролирует система — минимальный интервал 15–30 минут, для критичных данных используется push-to-refresh. На Android интервал задаётся в updatePeriodMillis (минимум 30 минут) или через WorkManager для фоновых задач.

Какие размеры поддерживает Widget?

iOS поддерживает small (170x170pt), medium (360x170pt) и large (360x380pt). Android использует гибкую сетку ячеек: от 2x1 до 5x5, размер зависит от launcher и версии ОС.

Можно ли добавить анимацию в Widget?

На iOS анимации внутри виджета отсутствуют — это статичные элементы. Android RemoteViews поддерживает базовые анимации через setFloat() и ViewPropertyAnimator, но сложные анимации недоступны.

Widget снижает производительность устройства?

При правильной реализации — нет. Система строго ограничивает ресурсы виджета: на iOS бюджет обновлений и памяти (30–50 МБ), на Android — минимальный интервал обновления. Проблемные виджеты система принудительно завершает.

Итоги

  • Widget — компактный элемент home screen для быстрого доступа к данным приложения без его открытия
  • iOS WidgetKit поддерживает три фиксированных размера и обновление через TimelineProvider с SwiftUI
  • Android AppWidgetProvider работает через BroadcastReceiver и RemoteViews с гибкими размерами ячеек
  • Обновление данных на обеих платформах ограничено системой: iOS — бюджет обновлений, Android — минимум 30 минут
  • Интерактивность появилась на iOS 17 (App Intents) и на Android 12 (динамические цвета, кнопки)
  • Smart Stack на iOS и стопки на Android позволяют группировать несколько виджетов с автопереключением
  • Производительность критична — система принудительно завершает проблемные виджеты при превышении лимитов

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также