I have a simple Widget with a ValueListenableBuilder
that listens to a ValueNotifier
.
The build function of the ValueListenablebuilder
is never triggered when updating the value of the ValueNotifier
from a native method call (using setMethodCallHandler
).
Instead, if I use valueNotifier.listen(() {})
, I'm able to receive new values even in the build function. The native code, in fact, emits a new String each second.
This is the minimal code to reproduce the issue:
class Main extends StatelessWidget {
Main({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
platform.invokeMethod("startNativeMethod");
platform.setMethodCallHandler(handleNativeMethod);
Future.delayed(Duration(seconds: 3)).then((value) {
// this WORKS and updates the Text!
resourceNotifier.value = "test";
});
resourceNotifier.addListener(() {
// this ALWAYS works (prints "test" and then native updates each second)
print(resourceNotifier.value);
});
return ValueListenableBuilder(
valueListenable: resourceNotifier,
builder: (context, String value, child) {
// this is triggered only with "test"
// (when updated from Future.delayed)
return Container(child: Text(value ?? "Empty"));
});
}
ValueNotifier<String> resourceNotifier = ValueNotifier(null);
MethodChannel platform = const MethodChannel("com.example.example");
Future<dynamic> handleNativeMethod(MethodCall call) async {
// this NEVER updates the Text() widget. Always triggers the listener instead.
resourceNotifier.value = "hello from native";
}
}
This goes also beyond ValueNotifiers. I've also tried moving to a Stateful Widget and setting state from handleNativeMethod. Even setState
doesn't work from there.
Thanks in advance for the help!