Multiple Widgets
Each top-level final or const variable of type AndroidWidget in your lib/ folder becomes its own home screen widget. There's no extra configuration — just declare them.
Defining multiple widgets
// lib/widgets.dart
import 'package:flutter_android_widgets/flutter_android_widgets.dart';
final weatherWidget = AndroidWidget(
info: WidgetInfo(
widgetClassName: 'WeatherWidgetProvider',
widgetName: 'Weather',
minWidth: 250,
minHeight: 100,
updateInterval: Duration(hours: 1),
),
layout: WColumn(
backgroundColor: '#1A237E',
padding: 12,
children: [
WText('\${temperature}', textSize: 36, bold: true, textColor: '#FFFFFF'),
WText('\${condition}', textSize: 14, textColor: '#B0BEC5'),
],
),
dataKeys: ['temperature', 'condition'],
);
final todoWidget = AndroidWidget(
info: WidgetInfo(
widgetClassName: 'TodoWidgetProvider',
widgetName: 'Todo List',
minWidth: 250,
minHeight: 200,
updateInterval: Duration(minutes: 30),
),
layout: WColumn(
backgroundColor: '#263238',
padding: 12,
children: [
WText('Tasks', textSize: 16, bold: true, textColor: '#FFFFFF'),
WText('\${task1}', textSize: 14, textColor: '#CFD8DC'),
WText('\${task2}', textSize: 14, textColor: '#CFD8DC'),
WText('\${task3}', textSize: 14, textColor: '#CFD8DC'),
WButton(label: 'Refresh', actionKey: 'refreshTodo'),
],
),
dataKeys: ['task1', 'task2', 'task3'],
);What gets generated
Running build_runner produces separate files for each widget:
| Widget | XML layout | Provider XML | Kotlin class |
|---|---|---|---|
weatherWidget | widget_weather_widget_provider.xml | appwidget_provider_weather_widget_provider.xml | WeatherWidgetProvider.kt |
todoWidget | widget_todo_widget_provider.xml | appwidget_provider_todo_widget_provider.xml | TodoWidgetProvider.kt |
Both <receiver> entries are patched into AndroidManifest.xml together.
Sending data to multiple widgets
Data keys are global across all widgets. Use distinct key names to avoid collisions:
// Weather data
await HomeWidgetData.saveAll({
'temperature': '72°F',
'condition': 'Sunny',
});
// Todo data
await HomeWidgetData.saveAll({
'task1': '✓ Buy groceries',
'task2': '○ Call dentist',
'task3': '○ Review PR',
});Passing all widgets to WidgetUpdater
Pass the full list to initialize() so all widget styles sync on hot restart:
void main() {
WidgetsFlutterBinding.ensureInitialized();
WidgetUpdater.initialize(widgets: [weatherWidget, todoWidget]);
HomeWidgetData.autoUpdate = true;
runApp(const MyApp());
}Widgets across multiple files
You can spread widget definitions across multiple files. The builder scans all .dart files under lib/:
lib/
├── widgets/
│ ├── weather_widget.dart ← final weatherWidget = AndroidWidget(...)
│ ├── todo_widget.dart ← final todoWidget = AndroidWidget(...)
│ └── stats_widget.dart ← final statsWidget = AndroidWidget(...)
└── main.dartAction key uniqueness
Button actionKey values must be globally unique across all widgets. The generator creates a broadcast action constant per key:
actionKey: 'refresh' → ACTION_REFRESH = "com.example.myapp.ACTION_REFRESH"
actionKey: 'refreshTodo' → ACTION_REFRESHTODO = "com.example.myapp.ACTION_REFRESHTODO"Using the same actionKey in two different widgets would cause both to respond to the same broadcast — leading to unexpected behavior.