Flutter global notification local flush singleton
Recently summarized the partial refresh of Flutter, mainly
InheritedWidget 2, ValueNotifier 3, StreamBuilder 4, StatefulBuilder 5, Globalkey
1.
class MyInheritedWidget extends InheritedWidget { final int count; MyInheritedWidget(Widget child, this.count) : super(child: child); Static MyInheritedWidget of(BuildContext Context) {return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>(); } @override bool updateShouldNotify(MyInheritedWidget oldWidget) { return oldWidget.count! =this.count; }} // Only child MyInheritedWidget.of(context).count is refreshed when called in childCopy the code
2 ValueNotifier is similar to KVO. ValueNotifier monitors the changes of observers and refreshes local values in a one-to-one manner
ValueNotifier<String> _name = ValueNotifier<String>(''); ValueListenableBuilder( builder: (context, value, child) { return Text(value); }, valueListenable: _name, child: Text(' have you changed '),); ValueNotifier<String> _name = ValueNotifier<String>(''); _name. Value = 'I have changed';Copy the code
StreamBuilder is similar to notifications that are sent by registering them for partial refresh, one-to-many value refresh, and note destruction
StreamController<String> _streamController; _streamController = StreamController<String>(); StreamBuilder(stream: _streamController.stream, builder: (BuildContext context, AsyncSnapshot<String> snapshot) { if (snapshot.hasData) { return Text(snapshot.data); } return Text(' no data received '); }, ) @override dispose() { super.dispose(); _streamController.close(); } // send _streamController.add(' I've changed ');Copy the code
4 StatefulBuilder is similar to the transmission of values through the transmission of local setState to perform local refresh and local refresh in space. The scope of application is limited and it is mostly used for AlertDialog and Bottomsheet
StatefulBuilder( builder: (BuildContext context, StateSetter setState) { return Column( mainAxisSize: MainAxisSize.min, children: List<Widget>.generate(4, (int index) { return Radio<int>( value: index, groupValue: selectedRadio, onChanged: (int value) { setState(() => selectedRadio = value); }); })); })Copy the code
Used alone, the above can only be refreshed within a class, but it can be refreshed globally with the Provider
5 Globalkey is a full-tree lookup, which is easy to use, but is best avoided for complex projects;
encapsulation
abstract class GlobalKeyRefreshableWidget extends StatefulWidget {
GlobalKeyRefreshableWidget({Key key})
: super(key: key is GlobalKey ? key : GlobalKey());
void reload() {
if (key is! GlobalKey) {
return;
}
final aKey = key as GlobalKey;
// ignore: invalid_use_of_protected_member
aKey.currentState.setState(() {});
}
}
class RefreshableStatefulWidget extends GlobalKeyRefreshableWidget {
final Widget Function(BuildContext cntext) builder;
RefreshableStatefulWidget({Key key, @required this.builder})
: assert(builder != null),
super(key: key);
@override
State<StatefulWidget> createState() {
return _RefreshableViewState(builder);
}
}
class _RefreshableViewState extends State<RefreshableStatefulWidget> {
final Widget Function(BuildContext cntext) builder;
_RefreshableViewState(this.builder);
@override
Widget build(BuildContext context) {
return builder(context);
}
}
Copy the code
use
_aRefreshableView = RefreshableStatefulWidget(builder: (BuildContext context) { return Container( ... ) ; } _aRefreshableView.reload();Copy the code
Global notification through singleton mode imitation notification, easy to use, extensible and understandable:
Class NotificationCenter {// Factory mode Factory NotificationCenter() => _getInstance(); static NotificationCenter get instance => _getInstance(); static NotificationCenter _instance; Notificationcenter._internal () {// Initialize} // singleton static notificationCenter_getInstance () {if (_instance == null) { _instance = new NotificationCenter._internal(); } return _instance; } // create a Map to record the name Map<String, dynamic> postNameMap = Map<String, dynamic>(); Map<String, GetObject> getObject = Map<String, GetObject>(); // Add listener method addObserver(String postName, object(Dynamic Object)) {postNameMap[postName] = null; getObject[postName] = object; } // postNotification(String postName, If (postnamemap.containsKey (postName)) {postNameMap[postName] = object; getObject[postName](object); }} // removeNotification(String postName) {if (postnamemap.containsKey (postName)) {postnamemap.remove (postName); }}}Copy the code
Use:
NotificationCenter.instance.postNotification('HomeRefreash', 'refreash');
Copy the code
Registration:
NotificationCenter.instance.addObserver('HomeRefreash', (object){
}
Copy the code
Remember to destroy
NotificationCenter.instance.removeNotification('HomeRefreash');
Copy the code
I have just started to make a summary. There will certainly be loopholes of this kind and that, and there will definitely be safer and more convenient methods. I hope you can correct me.