Flutter Widgets

Everything in Flutter is a widget. Text, buttons, images, layouts — all widgets. Your app is a tree of widgets nested inside each other.

StatelessWidget vs StatefulWidget

Dart
// Stateless — no mutable state, just displays data
class Greeting extends StatelessWidget {
  final String name;
  const Greeting({super.key, required this.name});

  @override
  Widget build(BuildContext context) {
    return Text('Hello, $name!');
  }
}

// Stateful — can change over time
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: const Text('Increment'),
        ),
      ],
    );
  }
}

Common Widgets

Dart
// Text with styling
Text('Hello', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold))

// Buttons
ElevatedButton(onPressed: () {}, child: Text('Click me'))
TextButton(onPressed: () {}, child: Text('Text button'))
IconButton(onPressed: () {}, icon: Icon(Icons.star))

// Images
Image.network('https://example.com/photo.jpg')
Image.asset('assets/logo.png')

// Container (box with padding, margin, decoration)
Container(
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.symmetric(horizontal: 8),
  decoration: BoxDecoration(
    color: Colors.blue[50],
    borderRadius: BorderRadius.circular(12),
  ),
  child: Text('Styled box'),
)

Layout Widgets

Dart
// Row — horizontal
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [Text('A'), Text('B'), Text('C')],
)

// Column — vertical
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [Text('First'), Text('Second'), Text('Third')],
)

// Stack — overlapping
Stack(
  children: [
    Image.network('photo.jpg'),
    Positioned(
      bottom: 8, left: 8,
      child: Text('Label', style: TextStyle(color: Colors.white)),
    ),
  ],
)

// Expanded — fills remaining space
Row(
  children: [
    Expanded(flex: 2, child: Container(color: Colors.red)),
    Expanded(flex: 1, child: Container(color: Colors.blue)),
  ],
)

Padding and Spacing

Dart
Padding(
  padding: EdgeInsets.all(16),
  child: Text('Padded content'),
)

SizedBox(height: 20) // invisible spacer
Divider()            // horizontal line

Tips

  • Use const constructors when possible — Flutter skips rebuilding const widgets.
  • Prefer StatelessWidget unless you need mutable state.
  • Use Expanded and Flexible inside Row/Column to control layout.
  • Keep widget trees shallow — extract into separate widgets when nesting deepens.

Next: state.