소스 정보
- 저장소
- xuelongqy/flutter_easy_refresh
- 최근 소스 활동
- 2026년 3월 19일 16:33
- 감지된 SKILL.md 언어
- 영어
- 스타
- 4,069
- 포크
- 654
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/xuelongqy/flutter_easy_refresh --skill flutter-home-screen-widget명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | flutter-home-screen-widget |
| description | Adding a Home Screen widget to your Flutter App |
| metadata | {"model":"models/gemini-3.1-pro-preview","last_modified":"Fri, 06 Mar 2026 20:49:44 GMT"} |
Implements native home screen widgets (iOS and Android) for a Flutter application using the home_widget package. It establishes data sharing between the Dart environment and native platforms via App Groups (iOS) and SharedPreferences (Android), enabling text updates and rendering Flutter UI components as images for native display. Assumes a pre-existing Flutter project environment with native build tools (Xcode and Android Studio) configured.
Initialize Dependencies
Add the home_widget package to the Flutter project.
flutter pub add home_widget
flutter pub get
Decision Logic: Platform & Feature Selection Determine the target platforms and required widget capabilities. [BLOCKING] User Consultation BEFORE performing any implementation, you MUST ask:
Flowchart:
Implement Dart Data Sharing Logic Create the Dart logic to save data to the native key/value store and trigger widget updates.
import 'package:home_widget/home_widget.dart';
// Replace with actual App Group ID for iOS
const String appGroupId = 'group.com.yourcompany.app';
const String iOSWidgetName = 'NewsWidgets';
const String androidWidgetName = 'NewsWidget';
Future<void> updateWidgetData(String title, String description) async {
await HomeWidget.setAppGroupId(appGroupId);
await HomeWidget.saveWidgetData<String>('headline_title', title);
await HomeWidget.saveWidgetData<String>('headline_description', description);
await HomeWidget.updateWidget(
iOSName: iOSWidgetName,
androidName: androidWidgetName,
);
}
iOS Native Setup (If applicable)
NewsWidgets). Uncheck "Include Live Activity" and "Include Configuration Intent".TimelineProvider and View in Swift:import WidgetKit
import SwiftUI
struct NewsArticleEntry: TimelineEntry {
let date: Date
let title: String
let description: String
}
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> NewsArticleEntry {
NewsArticleEntry(date: Date(), title: "Placeholder Title", description: "Placeholder description")
}
func getSnapshot(in context: Context, completion: @escaping (NewsArticleEntry) -> ()) {
let entry: NewsArticleEntry
if context.isPreview {
entry = placeholder(in: context)
} else {
// Replace with actual App Group ID
let userDefaults = (suiteName: )
title userDefaults.string(forKey: )
description userDefaults.string(forKey: )
entry (date: (), title: title, description: description)
}
completion(entry)
}
( : , : (<>) -> ()) {
getSnapshot(in: context) { (entry)
timeline (entries: [entry], policy: .atEnd)
completion(timeline)
}
}
}
: {
entry: .
body: {
(alignment: .leading) {
(entry.title).font(.headline)
(entry.description).font(.subheadline)
}
}
}
Android Native Setup (If applicable)
AppWidgetProvider in Android Studio (New -> Widget -> App Widget).res/layout/news_widget.xml):<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<TextView
android:id="@+id/headline_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textStyle="bold"
android:textSize="20sp" />
<TextView
android:id="@+id/headline_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/headline_title"
android:text="Description"
android:textSize="16sp" />
</RelativeLayout>
NewsWidget.kt):Render Flutter Widgets as Images (Optional) If the user requires complex UI (like charts) on the widget, render the Flutter widget to a PNG and pass the file path. Dart Implementation:
final _globalKey = GlobalKey();
// Wrap your target widget with a RepaintBoundary/Key
// Center(key: _globalKey, child: const LineChart())
Future<void> renderAndSaveWidget() async {
if (_globalKey.currentContext != null) {
var path = await HomeWidget.renderFlutterWidget(
const LineChart(),
fileName: 'screenshot',
key: 'filename',
logicalSize: _globalKey.currentContext!.size,
pixelRatio: MediaQuery.of(_globalKey.currentContext!).devicePixelRatio,
);
await HomeWidget.updateWidget(iOSName: iOSWidgetName, androidName: androidWidgetName);
}
}
Native Image Loading (Android Example):
// Inside RemoteViews apply block:
val imageName = widgetData.getString("filename", null)
val imageFile = java.io.File(imageName)
if (imageFile.exists()) {
val myBitmap = android.graphics.BitmapFactory.decodeFile(imageFile.absolutePath)
setImageViewBitmap(R.id.widget_image, myBitmap)
}
iOSName and androidName in Dart MUST exactly match the Swift struct name and Kotlin class name respectively.group. and match exactly in Xcode capabilities, Swift UserDefaults(suiteName:), and Dart HomeWidget.setAppGroupId().renderFlutterWidget to generate a static image if complex UI is required.flutter run.res/xml/*_info.xml must be calculated in cells (e.g., minWidth="250dp"). Do not use arbitrary pixel values.flutter build ios / flutter build apk) after modifying native files to catch syntax or linking errors immediately.Validate-and-Fix: Run flutter build ios --config-only to ensure the Flutter configuration syncs with the new Xcode targets. If build fails, verify the App Group ID matches exactly between Dart and Swift.
package com.yourdomain.yourapp
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.widget.RemoteViews
import es.antonborri.home_widget.HomeWidgetPlugin
class NewsWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
for (appWidgetId in appWidgetIds) {
val widgetData = HomeWidgetPlugin.getData(context)
val views = RemoteViews(context.packageName, R.layout.news_widget).apply {
val title = widgetData.getString("headline_title", null)
setTextViewText(R.id.headline_title, title ?: "No title set")
val description = widgetData.getString("headline_description", null)
setTextViewText(R.id.headline_description, description ?: "No description set")
}
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
}