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 MB и време за формиране на 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 изисква нова времева линия. От 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 задава минимални размери, интервал и оформление: 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 MB), на 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също