Flutter Multi-Platform Development
Flutter Widgets Overview

1. What is a Stateless Widget?
A StatelessWidget doesn’t have a state that changes over time. It’s used for static content.
Example: Text, icons, or a static UI like a title bar.
import 'package:flutter/material.dart';
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Stateless Widget")),
body: Center(
child: Text("This doesn't change!", style: TextStyle(fontSize: 24)),
),
);
}
}
2. What is a Stateful Widget?
A StatefulWidget can rebuild (change its UI) based on user interaction or other events. It maintains a "state."
Example: A counter that updates when a button is pressed.
import 'package:flutter/material.dart';
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int counter = 0; // State variable
void incrementCounter() {
setState(() { // Notify the widget to rebuild
counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Stateful Widget")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: $counter', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: incrementCounter,
child: Text('Increment'),
),
],
),
),
);
}
}
3. When to Use Stateful vs Stateless?
Ask yourself:
- Does anything change in this widget?
- Yes: Use StatefulWidget.
- No: Use StatelessWidget.
Examples:
- Stateless: Static UI, text, icons, layouts.
- Stateful: UI that changes due to user interaction (e.g., forms, animations, buttons).
4. What About ConsumerWidget (Riverpod)?
A ConsumerWidget is like a StatelessWidget, but it can listen to state changes from Riverpod providers.
You don’t need a StatefulWidget if you're using Riverpod because state is managed externally by providers.
5. How to Decide with Riverpod?
Use StatelessWidget/ConsumerWidget:
- When all state is managed by providers.
Example: Watching a StateProvider or StateNotifierProvider.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final counterProvider = StateProvider<int>((ref) => 0);
class CounterScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
return Scaffold(
appBar: AppBar(title: Text("Counter with ConsumerWidget")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: $counter', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: () {
ref.read(counterProvider.notifier).state++;
},
child: Text('Increment'),
),
],
),
),
);
}
}
Use StatefulWidget:
- When you don’t use Riverpod or need temporary local state (like animations or text input focus).
6. Quick Comparison
Feature | StatelessWidget | StatefulWidget | ConsumerWidget |
---|---|---|---|
State Management | No | Local to widget | Managed by Riverpod |
Rebuild Behavior | Static UI | Rebuilds on setState | Rebuilds when provider changes |
Best Use | Static UIs | Interactive UIs | Apps with global state (using Riverpod) |
Key Takeaway:
If you're using Riverpod, ConsumerWidget is enough for managing state. Use StatefulWidget only for local/temporary state not managed by providers.