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.