zoukankan      html  css  js  c++  java
  • Flutter-notification和notificatioLisener

    Notification源码:

    abstract class Notification {
      /// Abstract const constructor. This constructor enables subclasses to provide
      /// const constructors so that they can be used in const expressions.
      const Notification();
    
      /// Applied to each ancestor of the [dispatch] target.
      ///
      /// The [Notification] class implementation of this method dispatches the
      /// given [Notification] to each ancestor [NotificationListener] widget.
      ///
      /// Subclasses can override this to apply additional filtering or to update
      /// the notification as it is bubbled (for example, increasing a `depth` field
      /// for each ancestor of a particular type).
      @protected
      @mustCallSuper
      bool visitAncestor(Element element) {
        if (element is StatelessElement) {
          final StatelessWidget widget = element.widget;
          if (widget is NotificationListener<Notification>) {
            if (widget._dispatch(this, element)) // that function checks the type dynamically
              return false;
          }
        }
        return true;
      }
    
      /// Start bubbling this notification at the given build context.
      ///
      /// The notification will be delivered to any [NotificationListener] widgets
      /// with the appropriate type parameters that are ancestors of the given
      /// [BuildContext]. If the [BuildContext] is null, the notification is not
      /// dispatched.
      void dispatch(BuildContext target) {
        // The `target` may be null if the subtree the notification is supposed to be
        // dispatched in is in the process of being disposed.
        target?.visitAncestorElements(visitAncestor);
      }
    
      @override
      String toString() {
        final List<String> description = <String>[];
        debugFillDescription(description);
        return '$runtimeType(${description.join(", ")})';
      }
    
      /// Add additional information to the given description for use by [toString].
      ///
      /// This method makes it easier for subclasses to coordinate to provide a
      /// high-quality [toString] implementation. The [toString] implementation on
      /// the [Notification] base class calls [debugFillDescription] to collect
      /// useful information from subclasses to incorporate into its return value.
      ///
      /// If you override this, make sure to start your method with a call to
      /// `super.debugFillDescription(description)`.
      @protected
      @mustCallSuper
      void debugFillDescription(List<String> description) { }
    }

    其中dispatch(context)是分发通知的,它会从参数context位置处开始沿着widget树向上冒泡通知。

    也可以自定义Notification,比如class MyNotification extends Notification( final String msg; MyNotification(this.msg);)

    NotificationListener是用来监听Notification的,源码如下:

    /// A widget that listens for [Notification]s bubbling up the tree.
    ///
    /// Notifications will trigger the [onNotification] callback only if their
    /// [runtimeType] is a subtype of `T`.
    ///
    /// To dispatch notifications, use the [Notification.dispatch] method.
    class NotificationListener<T extends Notification> extends StatelessWidget {
      /// Creates a widget that listens for notifications.
      const NotificationListener({
        Key key,
        @required this.child,
        this.onNotification,
      }) : super(key: key);
    
      /// The widget directly below this widget in the tree.
      ///
      /// This is not necessarily the widget that dispatched the notification.
      ///
      /// {@macro flutter.widgets.child}
      final Widget child;
    
      /// Called when a notification of the appropriate type arrives at this
      /// location in the tree.
      ///
      /// Return true to cancel the notification bubbling. Return false (or null) to
      /// allow the notification to continue to be dispatched to further ancestors.
      ///
      /// The notification's [Notification.visitAncestor] method is called for each
      /// ancestor, and invokes this callback as appropriate.
      ///
      /// Notifications vary in terms of when they are dispatched. There are two
      /// main possibilities: dispatch between frames, and dispatch during layout.
      ///
      /// For notifications that dispatch during layout, such as those that inherit
      /// from [LayoutChangedNotification], it is too late to call [State.setState]
      /// in response to the notification (as layout is currently happening in a
      /// descendant, by definition, since notifications bubble up the tree). For
      /// widgets that depend on layout, consider a [LayoutBuilder] instead.
      final NotificationListenerCallback<T> onNotification;
    
      bool _dispatch(Notification notification, Element element) {
        if (onNotification != null && notification is T) {
          final bool result = onNotification(notification);
          return result == true; // so that null and false have the same effect
        }
        return false;
      }
    
      @override
      Widget build(BuildContext context) => child;
    }

    其中属性child是子widget,onNotification是监听到了通知产生的回调。

    一个例子:

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    void main() => runApp(BuilderApp());
    
    class BuilderApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: NotificationRoute(),
        );
      }
    }
    
    class NotificationRoute extends StatefulWidget {
      @override
      NotificationRouteState createState() {
        return new NotificationRouteState();
      }
    }
    
    class NotificationRouteState extends State<NotificationRoute> {
      String _msg="";
      @override
      Widget build(BuildContext context) {
        //监听通知
        return NotificationListener<MyNotification>(
          onNotification: (notification) {
            setState(() {
              _msg+=notification.msg+"  ";
            });
            return true;
          },
          child: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
    //          RaisedButton(
    //           onPressed: () => MyNotification("Hi").dispatch(context),
    //           child: Text("Send Notification"),
    //          ),
                Builder(
                  builder: (context) {
                    return RaisedButton(
                      //按钮点击时分发通知
                      onPressed: () => MyNotification("Hi").dispatch(context),
                      child: Text("Send Notification"),
                    );
                  },
                ),
                Text(_msg)
              ],
            ),
          ),
        );
      }
    }
    
    class MyNotification extends Notification {
      MyNotification(this.msg);
      final String msg;
    }

    onNotification的方法需要返回bool值,返回true,表示当前事件不在向上传递,false表示继续向上传递

  • 相关阅读:
    面向对象方法与调用
    LeetCode OJ:Spiral Matrix(螺旋矩阵)
    LeetCode OJ:Jump Game(跳跃游戏)
    LeetCode OJ:Word Search(单词查找)
    LeetCode OJ:Majority Element II(主元素II)
    LeetCode OJ:Maximum Subarray(子数组最大值)
    LeetCode OJ:Next Permutation(下一排列)
    LeetCode OJ:Product of Array Except Self(除己之外的元素乘积)
    LeetCode OJ:Remove Duplicates from Sorted Array II(移除数组中的重复元素II)
    LeetCode OJ:Best Time to Buy and Sell Stock II(股票买入卖出最佳实际II)
  • 原文地址:https://www.cnblogs.com/FdWzy/p/13522841.html
Copyright © 2011-2022 走看看