API Reference
AndroidWidget
The root definition object. One top-level variable = one home screen widget.
const AndroidWidget({
required WidgetInfo info,
required WidgetNode layout,
List<String> dataKeys = const [],
})Validation rules:
dataKeysmust not be empty stringsdataKeysmust not contain duplicates
WidgetInfo
Metadata that maps to appwidget_provider.xml attributes.
const WidgetInfo({
required String widgetClassName, // PascalCase Kotlin class name
required String widgetName, // Label shown in the widget picker
required int minWidth, // dp — minimum width hint for launcher
required int minHeight, // dp — minimum height hint for launcher
required Duration updateInterval, // Auto-refresh interval (clamped to 30 min)
WidgetResizeMode resizeMode = WidgetResizeMode.both,
String? previewImage, // Optional drawable name for widget picker preview
})Notes:
widgetClassNameis converted tosnake_casefor resource file naming:MyWidgetProvider→my_widget_providerupdateIntervalis clamped to Android's 30-minute minimum (updatePeriodMillis = max(ms, 1_800_000))
WidgetResizeMode
enum WidgetResizeMode {
none, // Fixed size, no user resize
horizontal, // User can resize horizontally
vertical, // User can resize vertically
both, // User can resize in both directions (default)
}Layout nodes
Base properties (all nodes)
| Property | Type | Description |
|---|---|---|
id | String? | Explicit Android view ID — auto-generated if omitted |
padding | int? | Uniform padding in dp |
backgroundColor | String? | Hex color string (e.g. '#1A1A2E') |
WColumn / WRow
WColumn({
required List<WidgetNode> children,
String? backgroundColor,
int? padding,
String? gravity, // 'start' | 'center' | 'end'
String? id,
})WRow has the same signature — it renders as a horizontal LinearLayout.
WStack
WStack({
required List<WidgetNode> children,
String? backgroundColor,
int? padding,
String? id,
})WText
WText(
String text, // content; can contain \${key} placeholders
{
double? textSize, // sp units
String? textColor, // hex color
bool? bold, // maps to android:textStyle="bold"
int? maxLines, // truncates with ellipsis
String? gravity, // 'start' | 'center' | 'end'
String? backgroundColor,
int? padding,
String? id,
}
)WButton
WButton({
required String label, // button text (runtime-updatable)
required String actionKey, // unique identifier — generates a broadcast action
double? textSize,
String? textColor,
String? backgroundColor,
int? padding,
String? id,
})WImage
WImage({
required String drawableName, // drawable resource name (no extension)
int? width, // dp
int? height, // dp
String? contentDescription,
String? backgroundColor,
int? padding,
String? id,
})WProgressBar
WProgressBar({
int progress = 0, // 0–100 (runtime-updatable)
int? width, // dp
int? height, // dp
String? backgroundColor,
int? padding,
String? id,
})HomeWidgetData
Runtime API for pushing data from Flutter to the widget. All data is stored as String.
class HomeWidgetData {
/// Set to true to automatically call updateAll() after every save.
static bool autoUpdate = false;
/// Save a single value.
static Future<void> save(String key, String value);
/// Read the current value for a key. Returns null if not set.
static Future<String?> read(String key);
/// Delete a key from storage.
static Future<void> remove(String key);
/// Save multiple key-value pairs atomically.
static Future<void> saveAll(Map<String, String> data);
}WidgetUpdater
Triggers widget refreshes and syncs style properties to SharedPreferences.
class WidgetUpdater {
/// Initializes auto-refresh on hot restart and app resume.
///
/// Pass [widgets] to enable dynamic styling — on every hot restart,
/// all style properties are written to SharedPreferences before the
/// widget refresh is triggered.
///
/// Call once in main(). Subsequent calls are no-ops.
static void initialize({List<AndroidWidget>? widgets});
/// Sends APPWIDGET_UPDATE broadcast to all widget providers.
static Future<void> updateAll();
/// Updates a specific widget by provider class name.
static Future<void> updateWidget(String className);
}All methods silently handle MissingPluginException — safe to call during tests or when the native channel is not registered.
Build runner
The package registers an AndroidWidgetBuilder in build.yaml. Run it with:
# One-time build
dart run build_runner build
# Rebuild and delete conflicting output files
dart run build_runner build --delete-conflicting-outputs
# Watch mode — rebuilds on file save
dart run build_runner watch