import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const MyApp());
}
class Counter1 extends ChangeNotifier {
int _counter = 0;
int get counter {
return _counter;
}
void increment() {
_counter = _counter + 1;
notifyListeners();
}
void reset() {
_counter = 0;
notifyListeners();
}
}
class Counter2 extends ChangeNotifier {
int _counter = 0;
int get counter {
return _counter;
}
void increment() {
_counter = _counter + 1;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: MultiProvider(providers: [
ChangeNotifierProvider(
create: (context) {
return Counter2();
},
),
ChangeNotifierProxyProvider<Counter2, Counter1>(
create: (context) {
return Counter1();
},
update: (BuildContext context, Counter2 value, Counter1? previous) {
if (previous == null) {
throw StateError("Counter1 is null");
}
value.removeListener(previous.reset); // To avoid multiple listener
value.addListener(previous.reset);
return previous;
},
),
], child: const MyHomePage()),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
var counter1 = Provider.of<Counter1>(context);
var counter2 = Provider.of<Counter2>(context);
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title:
const Text("Let's try to reset counter 1 when counter 2 increment"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Counter 1:',
),
Text(
'${counter1.counter}',
style: Theme.of(context).textTheme.headlineMedium,
),
ElevatedButton(
onPressed: counter1.increment,
child: const Text("Increment counter 1")),
const Text(
'Counter 2:',
),
Text(
'${counter2.counter}',
style: Theme.of(context).textTheme.headlineMedium,
),
ElevatedButton(
onPressed: counter2.increment,
child: const Text("Increment counter 2")),
],
),
),
);
}
}
Add a comment
|
1 Answer
To simplify the code, you can remove the manual adding and removing of listeners by using context.watch, which automatically listens for changes.
Here is my proposition:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Counter1 extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter = _counter + 1;
notifyListeners();
}
void reset() {
_counter = 0;
notifyListeners();
}
}
class Counter2 extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter = _counter + 1;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter2()),
ChangeNotifierProxyProvider<Counter2, Counter1>(
create: (_) => Counter1(),
update: (context, counter2, counter1) {
if (counter1 == null) throw ArgumentError.notNull('counter1');
return counter1;
},
),
],
child: MaterialApp(
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter1 = context.watch<Counter1>();
final counter2 = context.watch<Counter2>();
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title:
const Text("Let's try to reset counter 1 when counter 2 increment"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Counter 1: ${counter1.counter}',
style: const TextStyle(fontSize: 20)),
Text('Counter 2: ${counter2.counter}',
style: const TextStyle(fontSize: 20)),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
counter1.increment();
},
child: const Text('Increment Counter 1'),
),
ElevatedButton(
onPressed: () {
counter1.reset();
counter2.increment();
},
child: const Text('Increment Counter 2'),
),
],
),
),
);
}
}