Reputation: 2343
I am extract some logic from Stateful Widget to Provider with ChangeNotifier: class Model extends ChangeNotifier {...}
In my Stateful Widget I have:
if (mounted) {
setState(() {});
}
How I can check if Widget is mounted in Model?
For example how I can call:
if (mounted) {
notifyListeners();
}
Upvotes: 7
Views: 2995
Reputation: 849
you can just override notifyListeners like this
class Model extends ChangeNotifier {
@override
void notifyListeners() {
WidgetsBinding.instance.addPostFrameCallback((t) {
print("skip notify after ${t.inMilliseconds}ms");
super.notifyListeners();
});
}
}
no need additional variables / constructor modification
Upvotes: 0
Reputation: 21
Just use a custom ChangeNotifier class.
import 'package:flutter/cupertino.dart';
class CustomChangeNotifier extends ChangeNotifier {
bool isDisposed = false;
@override
void notifyListeners() {
if (!isDisposed) {
super.notifyListeners();
}
}
@override
void dispose() {
isDisposed = true;
super.dispose();
}
}
Upvotes: 0
Reputation: 1553
as long as you wrap your widget with the provider model state and as it is known once your widget is disposed the provider model that is wrapping it already get disposed by default
so all you have to do is to define a variable isDisposed and modify the notifyListeners as below
MyState with ChangeNotifier{
// to indicate whether the state provider is disposed or not
bool _isDisposed = false;
// use the notifyListeners as below
customNotifyListeners(){
if(!_isDisposed){
notifyListeners()
}
}
@override
void dispose() {
super.dispose();
_isDisposed = true;
}
}
Upvotes: 0
Reputation: 243
A simple way is pass 'State' of your Stateful Widget as a parameter to your 'Model'.
Like this:
class Model extends ChangeNotifier {
Model(this.yourState);
YourState yourState;
bool get _isMounted => yourState.mounted;
}
class YourState extends State<YourStatefulWidget> {
Model model;
@override
void initState() {
super.initState();
model = Model(this);
}
@override
Widget build(BuildContext context) {
// your code..
}
}
I think you don't need to check the State
is mounted or not. You just need to check the Model has been already disposed. You can override dispose()
method in ChangeNotifier
:
class Model extends ChangeNotifier {
bool _isDisposed = false;
void run() async {
await Future.delayed(Duration(seconds: 10));
if (!_isDisposed) {
notifyListeners();
}
}
@override
void dispose() {
super.dispose();
_isDisposed = true;
}
}
And don't forget dispose Model
when the State
is disposed:
class YourState extends State {
Model model;
@override
void initState() {
super.initState();
model = Model();
}
@override
void dispose() {
model?.dispose();
super.dispose();
}
/// Your build code...
}
Or you can use ChangeNotifierProvider
in package Provider, it will help you to dispose Model
automatically.
class YourState extends State {
Model model;
@override
void initState() {
super.initState();
model = Model();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Model>(
builder: (build) => model,
child: Container(
child: Consumer<Model>(
builder: (context, model, widget) => Text("$model"),
),
),
);
}
}
Upvotes: 8