Widget: nó là gì, widget trên iOS WidgetKit và Android

Tác giả: IT Sectr Đã đăng: 2026-02-15 Thời gian đọc: 10 phút

Widget là một phần tử giao diện người dùng nhỏ gọn trên màn hình chính iOS hoặc Android, hiển thị thông tin liên quan mà không cần mở ứng dụng. Widget xuất hiện trong iOS 14 (2020) với framework WidgetKit trên SwiftUI và đã tồn tại trên Android từ phiên bản 1.5 thông qua AppWidgetProvider trên Kotlin hoặc Java. Chúng cho phép người dùng xem thời tiết, tỷ giá hối đoái, lịch, ghi chú hoặc trạng thái nhiệm vụ trực tiếp trên màn hình chính, tiết kiệm thời gian và đơn giản hóa tương tác. Theo Apple, người dùng tương tác với widget trung bình 4–6 lần mỗi ngày và việc đặt widget trên màn hình chính làm tăng mức độ tương tác với ứng dụng lên 20–30%. Đối với Android, những con số này có thể so sánh được. Hãy cùng tìm hiểu cách widget hoạt động trên cả hai nền tảng với các ví dụ mã.

Những điểm chính

  • Widget — một ứng dụng nhỏ trên màn hình chính để xem nhanh thông tin mà không cần mở ứng dụng chính
  • iOS WidgetKit (iOS 14+) được xây dựng trên SwiftUI với ba kích thước và cập nhật qua TimelineProvider
  • Android AppWidgetProvider đã tồn tại từ API level 3 và sử dụng RemoteViews — một tập hợp View giới hạn trong một tiến trình riêng biệt
  • Cập nhật dữ liệu trên iOS — qua timeline chỉ định ngày, trên Android — qua updateIntervalMillis hoặc WorkManager
  • Smart Stack trên iOS và ngăn xếp widget trên Android cho phép nhóm nhiều widget vào một khe

Widget là gì

Widget là một phần tử giao diện người dùng nhỏ gọn được đặt trên màn hình chính của thiết bị di động để hiển thị thông tin liên quan từ ứng dụng. Không giống như ứng dụng đầy đủ, widget không yêu cầu khởi chạy — người dùng thấy dữ liệu ngay sau khi mở khóa màn hình. Khái niệm này bắt nguồn từ hệ điều hành máy tính để bàn (macOS Dashboard, Windows Sidebar), và trong môi trường di động, Android đã giới thiệu hỗ trợ widget ngay từ phiên bản đầu tiên (Android 1.5 Cupcake, 2009), trong khi Apple chỉ thêm chúng trong iOS 14.

Triển khai kỹ thuật khác nhau giữa các nền tảng. Widget iOS là một target riêng biệt trong Xcode, được biên dịch dưới dạng Widget Extension, chạy trong tiến trình riêng của nó. Widget Android là một BroadcastReceiver mở rộng AppWidgetProvider, hiển thị bố cục qua RemoteViews. Cả hai nền tảng đều áp đặt các hạn chế nghiêm ngặt về hiệu suất và bộ nhớ: hệ thống có thể xóa widget nếu vượt quá giới hạn. iOS giới hạn widget ở 30–50 MB và thời gian tạo timeline là 10 giây. Android — khoảng thời gian cập nhật không quá 30 phút qua updatePeriodMillis và buộc kết thúc nếu onUpdate bị treo.

Smart Stack trên iOS và ngăn xếp trên Android cho phép người dùng nhóm nhiều widget vào một khe trên màn hình chính. Thiết bị tự động chuyển đổi widget hiển thị dựa trên thời gian trong ngày, vị trí hoặc hoạt động của người dùng. Ví dụ, buổi sáng hiển thị lịch, ban ngày — thời tiết, buổi tối — ghi chú. Đối với nhà phát triển, điều này có nghĩa là widget phải hoạt động chính xác như một phần của ngăn xếp và không phụ thuộc vào việc hiển thị liên tục.

iOS WidgetKit: SwiftUI và TimelineProvider

WidgetKit là framework của Apple để tạo widget trên iOS 14+, iPadOS 14+ và macOS 11+. Widget được viết bằng Swift sử dụng SwiftUI và cơ chế TimelineProvider để cập nhật nội dung. Kiến trúc WidgetKit bao gồm ba thành phần: TimelineProvider — một nguồn dữ liệu tạo thành dòng thời gian với các mục; Widget Entry View — một SwiftUI View hiển thị nội dung dựa trên một mục; Widget Configuration — mô tả về loại, kích thước và họ của widget.

WidgetKit tự động quản lý cập nhật — nhà phát triển không thể buộc widget cập nhật thường xuyên hơn mức hệ thống cho phép. Apple sử dụng ngân sách cập nhật phân phối giữa tất cả các widget trên thiết bị. Khoảng thời gian tối thiểu là 15–30 phút. Đối với dữ liệu quan trọng (ví dụ: trạng thái giao hàng), push-to-refresh được sử dụng — gửi thông báo đẩy với ngày trong tương lai có liên quan, sau đó WidgetKit yêu cầu một dòng thời gian mới. Bắt đầu từ iOS 17, widget hỗ trợ tương tác qua App Intents — người dùng có thể nhấn nút bên trong widget mà không cần mở ứng dụng.

Kích thướciOS (pt)Nội dung
Small170 × 1701–2 chỉ số: nhiệt độ, tỷ giá hối đoái
Medium360 × 1702–4 chỉ số: dự báo 5 ngày, danh sách
Large360 × 3805–10 chỉ số: lịch, nguồn cấp tin tức

Android AppWidgetProvider: RemoteViews

AppWidgetProvider là lớp cơ sở để tạo widget trên Android, một phần của Android SDK từ API level 3. Widget Android là một BroadcastReceiver nhận các sự kiện cập nhật, kích hoạt và vô hiệu hóa từ hệ thống. Không giống như iOS, nơi widget được hiển thị bằng SwiftUI trên công cụ riêng của nó, Android sử dụng RemoteViews — một tập hợp giới hạn các thành phần View được hiển thị trong tiến trình hệ thống (trình khởi chạy). Không thể sử dụng View tùy chỉnh, hoạt ảnh phức tạp hoặc thư viện UI.

Quy trình làm việc của widget Android bao gồm bốn giai đoạn. Cấu hình — khi thêm widget vào màn hình, hệ thống có thể khởi chạy một Activity cấu hình nơi người dùng chọn cài đặt. Cập nhật — hệ thống gọi onUpdate() theo khoảng thời gian đã định (tối thiểu 30 phút) hoặc theo tín hiệu từ ứng dụng qua WorkManager. Hiển thị — nhà cung cấp tạo RemoteViews với dữ liệu hiện tại và chuyển chúng qua AppWidgetManager. Xử lý chạm — widget hỗ trợ PendingIntent cho các nút: nhấp chuột mở một Activity hoặc thực hiện một hành động. Bắt đầu từ Android 12, widget đã có hỗ trợ góc bo tròn, màu sắc thích ứng Material You và thay đổi kích thước động.

Tạo widget trên iOS với WidgetKit

Hãy tạo một widget thời tiết bằng Swift sử dụng WidgetKit và SwiftUI. Dự án phải bao gồm một target Widget Extension, được thêm trong Xcode qua File → New → Target → Widget Extension.

swift
import WidgetKit
import SwiftUI

// 1. Mô hình dữ liệu cho widget
struct WeatherEntry: TimelineEntry {
    let date: Date
    let temperature: Int
    let condition: String
}

// 2. TimelineProvider — nhà cung cấp dữ liệu
struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> WeatherEntry {
        WeatherEntry(date: Date(), temperature: 22, condition: "Nắng")
    }

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

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

// 3. SwiftUI View để hiển thị
struct WeatherWidgetEntryView: View {
    var entry: WeatherEntry

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

// 4. Cấu hình widget
@main
struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: "WeatherWidget", provider: Provider()) { entry in
            WeatherWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Thời tiết")
        .description("Hiển thị nhiệt độ hiện tại")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

Các điểm chính: TimelineProvider xác định khi nào và dữ liệu nào sẽ hiển thị; getTimeline tạo một dòng thời gian với chính sách cập nhật .after(nextUpdate); StaticConfiguration kết nối nhà cung cấp với View. Đối với dữ liệu động, IntentConfiguration được sử dụng với các tham số tùy chỉnh.

Tạo widget trên Android với AppWidgetProvider

Hãy triển khai một widget thời tiết tương tự bằng Kotlin với AppWidgetProvider và 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 = "Nhiều mây"
            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 — đăng ký nhà cung cấp
<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>

Tệp widget_weather_info.xml đặt kích thước tối thiểu, khoảng thời gian và bố cục: minWidth 160dp, minHeight 80dp, updatePeriodMillis 3600000 (1 giờ). RemoteViews chỉ sử dụng các thành phần được hỗ trợ: LinearLayout, TextView, ImageView. View tùy chỉnh và ConstraintLayout có sẵn từ Android 5.0. GlanceLayout — một cách tiếp cận thử nghiệm dựa trên Compose cho RemoteViews — xuất hiện trong Android 15.

Câu hỏi thường gặp

Sự khác biệt giữa Widget trên iOS và Android là gì?

iOS WidgetKit cung cấp ba kích thước cố định (small, medium, large) và cập nhật qua TimelineProvider với ngân sách hệ thống. Android AppWidgetProvider sử dụng kích thước linh hoạt dựa trên ô, RemoteViews để hiển thị và cập nhật qua updatePeriodMillis hoặc WorkManager.

Widget cập nhật bao lâu một lần?

Trên iOS, hệ thống kiểm soát cập nhật — khoảng thời gian tối thiểu là 15–30 phút, đối với dữ liệu quan trọng, push-to-refresh được sử dụng. Trên Android, khoảng thời gian được đặt trong updatePeriodMillis (tối thiểu 30 phút) hoặc qua WorkManager cho các tác vụ nền.

Widget hỗ trợ những kích thước nào?

iOS hỗ trợ small (170x170pt), medium (360x170pt) và large (360x380pt). Android sử dụng lưới ô linh hoạt: từ 2x1 đến 5x5, kích thước phụ thuộc vào trình khởi chạy và phiên bản hệ điều hành.

Tôi có thể thêm hoạt ảnh vào Widget không?

Trên iOS, hoạt ảnh bên trong widget không có sẵn — chúng là các phần tử tĩnh. Android RemoteViews hỗ trợ hoạt ảnh cơ bản qua setFloat() và ViewPropertyAnimator, nhưng hoạt ảnh phức tạp không có sẵn.

Widget có làm giảm hiệu suất thiết bị không?

Với triển khai đúng cách — không. Hệ thống giới hạn nghiêm ngặt tài nguyên widget: trên iOS — ngân sách cập nhật và bộ nhớ (30–50 MB), trên Android — khoảng thời gian cập nhật tối thiểu. Widget có vấn đề sẽ bị hệ thống buộc kết thúc.

Tổng kết

  • Widget — một phần tử nhỏ gọn trên màn hình chính để truy cập nhanh dữ liệu ứng dụng mà không cần mở nó
  • iOS WidgetKit hỗ trợ ba kích thước cố định và cập nhật qua TimelineProvider với SwiftUI
  • Android AppWidgetProvider hoạt động qua BroadcastReceiver và RemoteViews với kích thước ô linh hoạt
  • Cập nhật dữ liệu trên cả hai nền tảng bị giới hạn bởi hệ thống: iOS — ngân sách cập nhật, Android — tối thiểu 30 phút
  • Tương tác xuất hiện trên iOS 17 (App Intents) và Android 12 (màu sắc động, nút bấm)
  • Smart Stack trên iOS và ngăn xếp trên Android cho phép nhóm nhiều widget với chuyển đổi tự động
  • Hiệu suất rất quan trọng — hệ thống buộc kết thúc widget có vấn đề khi vượt quá giới hạn

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm