0
0
Fluttermobile~20 mins

Riverpod overview in Flutter - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Counter with Riverpod
A simple counter app that uses Riverpod to manage state. The app shows a number and a button to increase it.
Target UI
┌─────────────────────────┐
│       Counter App       │
├─────────────────────────┤
│                         │
│           0             │
│                         │
│      [+] Increment       │
│                         │
└─────────────────────────┘
Use Riverpod to create a provider for an integer counter state.
Display the current counter value in the center of the screen.
Add a button labeled '+' that increments the counter when tapped.
Use ConsumerWidget to listen to the provider and rebuild UI on changes.
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateProvider<int>((ref) => 0);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends ConsumerWidget {
  const CounterScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // TODO: Read counterProvider and build UI
    return Scaffold(
      appBar: AppBar(title: const Text('Counter App')),
      body: const Center(child: Text('0')),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.add),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateProvider<int>((ref) => 0);

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends ConsumerWidget {
  const CounterScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = ref.watch(counterProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('Counter App')),
      body: Center(
        child: Text(
          '$counter',
          style: const TextStyle(fontSize: 48),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          ref.read(counterProvider.notifier).state++;
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

This app uses Riverpod to manage the counter state simply and clearly.

We create a StateProvider<int> called counterProvider that holds the current count.

Inside CounterScreen, which is a ConsumerWidget, we use ref.watch(counterProvider) to get the current count and rebuild the UI when it changes.

The counter value is shown in a large text in the center.

The floating action button increments the counter by accessing the provider's notifier and increasing its state.

This shows how Riverpod helps keep state management clean and reactive.

Final Result
Completed Screen
┌─────────────────────────┐
│       Counter App       │
├─────────────────────────┤
│                         │
│           0             │
│                         │
│      [+] Increment       │
│                         │
└─────────────────────────┘
Tapping the [+] button increases the number in the center by 1 each time.
The number updates immediately without needing to restart the app.
Stretch Goal
Add a reset button in the app bar to set the counter back to zero.
💡 Hint
Add an IconButton in the AppBar actions that calls ref.read(counterProvider.notifier).state = 0 when pressed.