Quick reference for Flutter 3.x and Dart 3 — CLI commands, widget scaffolding, layout and common widgets, setState/Provider/Riverpod, go_router, and async patterns.
DartWidgetsState ManagementNavigation
CLI & Project Commands
# Environment
flutter --version
flutter doctor # check toolchain / devices
flutter devices # list connected devices/emulators
# Create + run
flutter create my_app
cd my_app
flutter run # run on default device
flutter run -d chrome # run on web
flutter run --release # AOT release build
# Packages
flutter pub add http go_router flutter_riverpod
flutter pub get
flutter pub upgrade
dart pub outdated
# Quality + build
flutter analyze
dart format .
flutter test
flutter build apk --release
flutter build ios --release
Widget Basics
Stateless & Stateful
// Stateless
class Label extends StatelessWidget {
const Label({super.key, required this.text});
final String text;
@override
Widget build(BuildContext context) => Text(text);
}
// Stateful
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int n = 0;
@override
Widget build(BuildContext context) => TextButton(
onPressed: () => setState(() => n++),
child: Text('$n'),
);
}
// App entry
void main() => runApp(const MaterialApp(home: Scaffold(body: Counter())));
Layout Widgets
Column(children: [a, b]) // vertical stack
Row(children: [a, b]) // horizontal stack
Stack(children: [a, b]) // overlap (z-order)
Expanded(flex: 2, child: w) // fill remaining space
Flexible(child: w) // fill up to needs
SizedBox(width: 8, height: 8) // fixed gap
Spacer() // flexible gap
Padding(padding: EdgeInsets.all(16), child: w)
Center(child: w)
Align(alignment: Alignment.topLeft, child: w)
Container(
padding: EdgeInsets.all(12),
margin: EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration(
color: Colors.teal,
borderRadius: BorderRadius.circular(12),
),
child: w,
)
Wrap(spacing: 8, children: chips) // wraps to next line
SingleChildScrollView(child: col) // scrollable content
Common Widgets (Material 3)
Scaffold(
appBar: AppBar(title: Text('Title')),
body: body,
floatingActionButton: FloatingActionButton(
onPressed: () {}, child: Icon(Icons.add)),
bottomNavigationBar: NavigationBar(destinations: [...]),
)
Text('Hi', style: TextStyle(fontSize: 18))
Icon(Icons.star, color: Colors.amber)
Image.network('https://...')
Image.asset('assets/logo.png')
FilledButton(onPressed: () {}, child: Text('Go'))
OutlinedButton(onPressed: () {}, child: Text('Cancel'))
IconButton(onPressed: () {}, icon: Icon(Icons.menu))
Card(child: ListTile(
leading: Icon(Icons.person),
title: Text('Name'),
trailing: Icon(Icons.chevron_right),
))
CircularProgressIndicator()
Divider(height: 1)
// Lists (lazy)
ListView.builder(
itemCount: items.length,
itemBuilder: (_, i) => Text(items[i]),
)
GridView.count(crossAxisCount: 2, children: tiles)
State Management
setState / Provider / Riverpod
// Local — setState
setState(() => _value = newValue);
// Provider (ChangeNotifier)
class Model extends ChangeNotifier {
int n = 0;
void inc() { n++; notifyListeners(); }
}
ChangeNotifierProvider(create: (_) => Model(), child: app);
context.watch<Model>().n; // rebuilds on change
context.read<Model>().inc(); // one-off call
// Riverpod (Notifier)
class Counter extends Notifier<int> {
@override
int build() => 0;
void inc() => state++;
}
final counterProvider = NotifierProvider<Counter, int>(Counter.new);
runApp(const ProviderScope(child: MyApp()));
ref.watch(counterProvider); // in a ConsumerWidget
ref.read(counterProvider.notifier).inc();
Navigation (go_router)
final router = GoRouter(routes: [
GoRoute(path: '/', builder: (_, __) => HomePage()),
GoRoute(
path: '/user/:id',
builder: (ctx, s) => UserPage(id: s.pathParameters['id']!),
),
]);
MaterialApp.router(routerConfig: router);
context.go('/user/42'); // replace stack
context.push('/settings'); // push route
context.pop(); // go back
// Imperative Navigator (no router)
Navigator.push(context,
MaterialPageRoute(builder: (_) => DetailPage()));
Navigator.pop(context, result);
Async Patterns
Future<int> work() async {
await Future.delayed(Duration(seconds: 1));
return 42;
}
final n = await work();
work().then((v) => print(v)).catchError((e) => print(e));
// FutureBuilder
FutureBuilder<int>(
future: work(),
builder: (ctx, snap) {
if (!snap.hasData) return CircularProgressIndicator();
if (snap.hasError) return Text('${snap.error}');
return Text('${snap.data}');
},
)
// HTTP
final res = await http.get(Uri.parse(url));
final data = jsonDecode(res.body);
// Streams
StreamBuilder<int>(stream: ticks, builder: (ctx, snap) => ...);
Useful Snippets
| Need | Snippet |
| Theme access | Theme.of(context) |
| Screen size | MediaQuery.sizeOf(context) |
| Snackbar | ScaffoldMessenger.of(context).showSnackBar(...) |
| Dialog | showDialog(context: context, builder: ...) |
| Async init | initState() + Future.microtask(...) |
| Dispose | controller.dispose() in dispose() |
| Debug print | debugPrint('msg') |
| Const perf | Prefer const constructors to skip rebuilds |