Everything in Flutter is a widget. Here’s a reference for the most commonly used widgets and their properties.
StatelessWidget
For widgets that don’t change over time. Their build method is called once.
class Greeting extends StatelessWidget {
final String name;
const Greeting({required this.name, super.key});
@override
Widget build(BuildContext context) {
return Text('Hello, $name!');
}
}StatefulWidget
For widgets that have mutable state. When state changes, build is called again.
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: () => setState(() => _count++),
child: Text('Increment'),
),
],
);
}
}Scaffold — page structure
Scaffold(
appBar: AppBar(
title: Text('My App'),
actions: [
IconButton(icon: Icon(Icons.settings), onPressed: () {}),
],
),
body: Center(child: Text('Hello')),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
bottomNavigationBar: NavigationBar(
destinations: [
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
NavigationDestination(icon: Icon(Icons.search), label: 'Search'),
],
),
drawer: Drawer(child: ListView(children: [])),
)Layout widgets
Column — vertical layout
Column(
mainAxisAlignment: MainAxisAlignment.center, // vertical alignment
crossAxisAlignment: CrossAxisAlignment.start, // horizontal alignment
mainAxisSize: MainAxisSize.min, // shrink-wrap
children: [
Text('First'),
Text('Second'),
Text('Third'),
],
)Row — horizontal layout
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // horizontal alignment
crossAxisAlignment: CrossAxisAlignment.center, // vertical alignment
children: [
Icon(Icons.star),
Text('Label'),
Icon(Icons.arrow_forward),
],
)Stack — overlapping widgets
Stack(
alignment: Alignment.center,
children: [
Image.asset('background.png'),
Positioned(
top: 20,
left: 20,
child: Text('Overlay'),
),
Positioned.fill(
child: Container(color: Colors.black.withOpacity(0.3)),
),
],
)Container — styling wrapper
Container(
width: 200,
height: 100,
padding: EdgeInsets.all(16),
margin: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 4,
offset: Offset(2, 2),
),
],
),
child: Center(child: Text('Hello')),
)ListView — scrollable list
// Fixed list
ListView(
padding: EdgeInsets.all(8),
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
],
)
// Dynamic list (lazy loading)
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index].name));
},
)
// Separated list
ListView.separated(
itemCount: items.length,
separatorBuilder: (context, index) => Divider(),
itemBuilder: (context, index) {
return ListTile(title: Text(items[index].name));
},
)GridView — grid layout
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 2 columns
mainAxisSpacing: 8,
crossAxisSpacing: 8,
childAspectRatio: 1.0, // width / height ratio
),
itemCount: items.length,
itemBuilder: (context, index) {
return Card(child: Center(child: Text(items[index].name)));
},
)Input widgets
// Text field
TextField(
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Enter your email',
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(),
),
onChanged: (value) => print(value),
keyboardType: TextInputType.emailAddress,
);
// Elevated button
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
child: Text('Submit'),
);
// Text button (no background)
TextButton(onPressed: () {}, child: Text('Learn More'));
// Icon button
IconButton(icon: Icon(Icons.favorite), onPressed: () {});
// Switch
Switch(value: isEnabled, onChanged: (val) => setState(() => isEnabled = val));
// Checkbox
Checkbox(value: isChecked, onChanged: (val) => setState(() => isChecked = val!));
// Slider
Slider(value: volume, min: 0, max: 100, onChanged: (val) => setState(() => volume = val));Dialog widgets
// AlertDialog
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Confirm'),
content: Text('Are you sure?'),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancel')),
ElevatedButton(onPressed: () => Navigator.pop(context, true), child: Text('OK')),
],
),
);
// BottomSheet
showModalBottomSheet(
context: context,
builder: (context) => Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Options'),
ListTile(title: Text('Option 1'), onTap: () => Navigator.pop(context)),
],
),
),
);
// Snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Item saved'), action: SnackBarAction(label: 'Undo', onPressed: () {})),
);