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 захтева нови 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 поставља минималне величине, интервал и распоред: 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. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође