Search code examples
flutterflutter-provider

Flutter/provider- initializing a state with a constructor


i am trying to understand how provider works in flutter and still i haven't figured out how to initialize a state using the state's constructor. Any tip?

here is the class the constructor is monitoring

class Counter extends ChangeNotifier{
  int _count;
  
  Counter(int initValue){

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

Solution

  • enter image description here

    First, you can simplify your ChangeNotifier to:

    class Counter extends ChangeNotifier {
      int count;
    
      Counter(this.count);
    
      void increment() {
        count++;
        notifyListeners();
      }
    }
    

    1. Create your ChangeNotifierProvider

    Now, define your ChangeNotifierProvider as:

    ChangeNotifierProvider<Counter>(
      create: (context) => Counter(10),
      child: child,
    ),
    

    This is where you provide the initial value of your Counter.

    2. Consume your ChangeNotifierProvider:

    Consumer<Counter>(
      builder: (context, counter, child) => Text(counter.count.toString()),
    

    3. Increment your ChangeNotifier Counter

    Provider.of<Counter>(context, listen: false).increment(),
    

    Here, remember to specify that you do not want to listen to your Provider.

    Full source Code

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    
    void main() {
      runApp(
        ChangeNotifierProvider<Counter>(
          create: (context) => Counter(10),
          child: MyApp(),
        ),
      );
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'StackOverflow Answer',
          home: Scaffold(
            body: Center(
              child: Consumer<Counter>(
                builder: (context, counter, child) => Text(
                  counter.count.toString(),
                  style: TextStyle(fontSize: 96),
                ),
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () =>
                  Provider.of<Counter>(context, listen: false).increment(),
              child: Icon(Icons.add),
            ),
          ),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    
    class Counter extends ChangeNotifier {
      int count;
    
      Counter(this.count);
    
      void increment() {
        count++;
        notifyListeners();
      }
    }
    

    Riverpod

    Note: If you are learning Provider, have a look at the Riverpod package, from the same author as Provider. It's much simpler, with less boiler plate:

    Here is the same example using Hooks Riverpod.

    1. Create your ChangeNotifierProvider

    The Provider is just a global variable that exists within the ProviderScope that we define on top of our MyApp.

    final counterProvider = ChangeNotifierProvider<Counter>((ref) => Counter(10));
    

    2. Consume your ChangeNotifierProvider:

    With Hooks Riverpos, consuming the Provider is made with useProvider at the beginning of the build method:

    final counter = useProvider(counterProvider);
    

    3. Increment your ChangeNotifier Counter

    This is as easy as reading the Provider from the current BuildContext and calling the method increment:

    context.read(counterProvider).increment(),
    
    import 'package:flutter/material.dart';
    import 'package:flutter_hooks/flutter_hooks.dart';
    import 'package:hooks_riverpod/hooks_riverpod.dart';
    
    void main() {
      runApp(
        ProviderScope(
          child: MyApp(),
        ),
      );
    }
    
    class MyApp extends HookWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(title: 'StackOverflow Answer', home: HomePage());
      }
    }
    
    class HomePage extends HookWidget {
      @override
      Widget build(BuildContext context) {
        final counter = useProvider(counterProvider);
        return Scaffold(
          body: Center(
            child: Text(
              counter.count.toString(),
              style: TextStyle(fontSize: 96),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => context.read(counterProvider).increment(),
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    final counterProvider = ChangeNotifierProvider<Counter>((ref) => Counter(10));
    
    class Counter extends ChangeNotifier {
      int count;
    
      Counter(this.count);
    
      void increment() {
        count++;
        notifyListeners();
      }
    }