Flutter Provider: How do I listen to a change of a class field inside a class field?
Here's an example on how you could use callback functions. Without the callback, A won't call notifyListeners
and your Home
widget doesnt get rebuild. Here's a short video on what a VoidCallback
is: https://www.youtube.com/watch?v=fWlPwj1Pp7U
Main function and a simple Home
view:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'a.dart';
void main() {
runApp(
ChangeNotifierProvider<A>(
create: (context) => A(),
child: MaterialApp(
home: Home(),
),
)
);
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<A>(
builder: (context, model, child) {
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('${model.element1.x}'),
RaisedButton(
child: Text("Set x of element1."),
onPressed: () {
Provider.of<A>(context, listen: false).element1.setX = 'Set to new value';
},
),
],
),
),
)
);
},
);
}
}
And then Class A:
import 'package:flutter/material.dart';
import 'package:tryout/b.dart';
class A extends ChangeNotifier {
B _element1 = B();
B _element2 = B();
B get element1 => _element1;
B get element2 => _element2;
A() {
_element1.callback = () => notifyListeners();
_element2.callback = () => notifyListeners();
}
set element1(B value) {
_element1 = value;
_element1.callback = () => notifyListeners();
notifyListeners();
}
set element2(B value) {
_element2 = value;
_element2.callback = () => notifyListeners();
notifyListeners();
}
}
And class B:
import 'package:flutter/cupertino.dart';
class B {
String x = "";
String y = "";
VoidCallback? callback;
B({
this.callback
});
set setX(String newValueX) {
x = newValueX;
if(callback != null) callback!();
}
void setY(String newValueY) {
y = newValueY;
if(callback != null) callback!();
}
}
THE-E
Updated on December 20, 2022Comments
-
THE-E over 1 year
Given the following Dart/Flutter class structure:
import 'package:flutter/material.dart'; class A with ChangeNotifier { B _element1; B _element2; B get element1 => _element1; B get element2 => _element2; set element1(B value) { _element1 = value; notifyListeners(); } set element2(B value) { _element2 = value; notifyListeners(); } } class B { String x; String y; }
I am trying to listen to a change of
A.element1.x
but the problem is, the setter of class B can't call thenotifyListeners()
of the class A, so either I am Listening to A and won't notice a change or I am listening to B and I am losing the context to A.I am using the Provider package in my Flutter project. But I am not sure, if I am misunderstanding the concept of Provider package or ChangeListeners. Either way I am not able to find a elegant solution.
Is there a possibility to overwrite the setter of class B from class A? I could obviously implement a function for each element1 and element2 fields(x,y). But this is not good code style I guess.
-
JJuice about 4 yearsThere’s multiple (as always;)) ways in which you could solve this: you could register a callback inside class B which then calls a function of class A, so that class A knows when to notify listeners because of changes in B. Or use a Stream, exposed by B and listened to by A. But maybe best is to look to ProxyProvider package. I don’t have experience with it but I think it could suit your use case. Here’s an article on it.
-
THE-E about 4 yearsCould you help me out with the callback function? I am not to familiar with callback functions. I looked into the article but could not see a solution for my particular problem. I also looked into the documentation, but couldn't figure out how to use ProxyProvider, to solve my problem as well.
-
JJuice about 4 yearsPosted an example below. This is how the callback calls the
notifyListeners
inside A. I am not sure if this is better than the alternative of just calling a method on A, which then sets the property on B and callsnotifyListeners
directly.
-