0
0
Fluttermobile~20 mins

Provider package in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Counter with Provider
A simple counter app that uses the Provider package to manage and share state across widgets.
Target UI
┌───────────────────────────┐
│       Counter App         │
├───────────────────────────┤
│                           │
│         0                 │
│                           │
│   [+]          [-]        │
│                           │
└───────────────────────────┘
Use Provider package to manage counter state.
Display the current counter value in the center.
Add two buttons: '+' to increment and '-' to decrement the counter.
Update the counter value reactively when buttons are pressed.
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter with Provider',
      home: // TODO: Wrap HomeScreen with Provider
    );
  }
}

class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void decrement() {
    _count--;
    notifyListeners();
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter with Provider')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // TODO: Display counter value
            // TODO: Add buttons to increment and decrement
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => Counter(),
      child: MaterialApp(
        title: 'Counter with Provider',
        home: const HomeScreen(),
      ),
    );
  }
}

class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void decrement() {
    _count--;
    notifyListeners();
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final counter = context.watch<Counter>();

    return Scaffold(
      appBar: AppBar(title: const Text('Counter with Provider')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              '${counter.count}',
              style: const TextStyle(fontSize: 48),
            ),
            const SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: counter.increment,
                  child: const Text('+'),
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  onPressed: counter.decrement,
                  child: const Text('-'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

We wrapped the entire app with ChangeNotifierProvider to provide the Counter instance to all widgets below. The Counter class extends ChangeNotifier and holds the counter state with methods to increment and decrement it, calling notifyListeners() to update the UI.

In HomeScreen, we use context.watch<Counter>() to listen for changes and rebuild the widget when the counter updates. The counter value is shown in a large text widget. Two buttons call the increment and decrement methods to update the counter reactively.

This setup cleanly separates state management from UI and uses Provider to share state easily.

Final Result
Completed Screen
┌───────────────────────────┐
│       Counter App         │
├───────────────────────────┤
│                           │
│          0                │
│                           │
│   [+]          [-]        │
│                           │
└───────────────────────────┘
Tapping '+' increases the number in the center by 1.
Tapping '-' decreases the number in the center by 1.
The displayed number updates immediately after each tap.
Stretch Goal
Add a reset button that sets the counter back to zero.
💡 Hint
Add a new method reset() in Counter that sets _count to 0 and calls notifyListeners(). Add a third button labeled 'Reset' that calls this method.