Reputation: 11
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();
}
}
Upvotes: 1
Views: 4946
Reputation: 8383
First, you can simplify your ChangeNotifier to:
class Counter extends ChangeNotifier {
int count;
Counter(this.count);
void increment() {
count++;
notifyListeners();
}
}
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
.
ChangeNotifierProvider
:Consumer<Counter>(
builder: (context, counter, child) => Text(counter.count.toString()),
ChangeNotifier
Counter
Provider.of<Counter>(context, listen: false).increment(),
Here, remember to specify that you do not want to listen to your Provider.
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();
}
}
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.
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));
ChangeNotifierProvider
:With Hooks Riverpos, consuming the Provider is made with useProvider
at the beginning of the build method:
final counter = useProvider(counterProvider);
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();
}
}
Upvotes: 6