美文网首页FlutterFlutter教学Flutter
Flutter(83):NotificationListener

Flutter(83):NotificationListener

作者: starryxp | 来源:发表于2020-11-24 10:21 被阅读0次

    Flutter教学目录持续更新中

    Github源代码持续更新中

    1.NotificationListener介绍

    widget通知监听

    2.NotificationListener属性

    • child:widget
    • onNotification:NotificationListenerCallback<Notification>,返回值true表示消费掉当前通知不再向上一级NotificationListener传递通知,false则会再向上一级NotificationListener传递通知;这里需要注意的是通知是由下而上去传递的,所以才会称作冒泡通知

    3.ScrollNotification

    ScrollNotification是一个抽象类,它的子类还有:

    • ScrollStartNotification:滑动开始通知
    • ScrollUpdateNotification:滑动中通知,滑动过程中会一直回调
    • ScrollEndNotification:滑动结束通知
    • OverscrollNotification:滑动位置未改变通知,这个一般只有在滑动到列表边界才会回调,且需要设置不可越界,即physics为ClampingScrollPhysics,这里要注意安卓默认是这样,但是ios平台默认是弹性边界
    • UserScrollNotification:用户滑动通知,这个跟ScrollUpdateNotification的区别是他指挥有滑动开始后以及滑动结束后回调

    4.Notification.ScrollMetrics属性

    • pixels:当前绝对位置
    • atEdge:是否在顶部或底部
    • axis:垂直或水平滚动
    • axisDirection:滚动方向描述是down还是up,这个受列表reverse影响,正序就是down倒序就是up,并不代表列表是上滑还是下滑
    • extentAfter:视口底部距离列表底部有多大
    • extentBefore:视口顶部距离列表顶部有多大
    • extentInside:视口范围内的列表长度
    • maxScrollExtent:最大滚动距离,列表长度-视口长度
    • minScrollExtent:最小滚动距离
    • viewportDimension:沿滚动方向视口的长度
    • outOfRange:是否越过边界

    4.使用

      _myChild() {
        return ListView.builder(
          itemBuilder: (context, index) => ListTile(title: Text('item $index')),
          itemCount: 30,
          reverse: true,
          // physics: BouncingScrollPhysics(),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('NotificationListener'),
          ),
          body: NotificationListener<ScrollNotification>(
            onNotification: (notification) {
              ScrollMetrics metrics = notification.metrics;
              print('ScrollNotification####################');
              print('pixels = ${metrics.pixels}');
              print('atEdge = ${metrics.atEdge}');
              print('axis = ${metrics.axis}');
              print('axisDirection = ${metrics.axisDirection}');
              print('extentAfter = ${metrics.extentAfter}');
              print('extentBefore = ${metrics.extentBefore}');
              print('extentInside = ${metrics.extentInside}');
              print('maxScrollExtent = ${metrics.maxScrollExtent}');
              print('minScrollExtent = ${metrics.minScrollExtent}');
              print('viewportDimension = ${metrics.viewportDimension}');
              print('outOfRange = ${metrics.outOfRange}');
              print('ScrollNotification####################');
              return false;
            },
            child: NotificationListener<ScrollUpdateNotification>(
              onNotification: (notification) {
                print('ScrollUpdateNotification####################');
                return false;
              },
              child: NotificationListener<OverscrollNotification>(
                onNotification: (notification) {
                  print('OverscrollNotification####################');
                  return false;
                },
                child: NotificationListener<ScrollStartNotification>(
                  onNotification: (notification) {
                    print('ScrollStartNotification####################');
                    return false;
                  },
                  child: NotificationListener<ScrollEndNotification>(
                    onNotification: (notification) {
                      print('ScrollEndNotification####################');
                      return false;
                    },
                    child: _myChild(),
                  ),
                ),
              ),
            ),
          ),
        );
      }
    
    image.png

    5.系统提供的其他Notification

    Notification是所有通知监听的顶级父类,它的子类有:

    • LayoutChangedNotification:这是一个空实现子类,他的子类有ScrollNotification,SizeChangedLayoutNotification
    • SizeChangedLayoutNotification:这是一个空实现子类,一般不会用到
    • DraggableScrollableNotification:DraggableScrollableSheet的拖拽通知,这个后面再介绍
    • OverscrollIndicatorNotification:这是滑动指示器的通知监听,例如Scrollbar,需要注意的是这个只有在滑动到头部或者尾部才会回调,而且滑动布局也需要是不可越界的,即physics为ClampingScrollPhysics
      这里的代码就在上期Flutter(82):Scroll组件之Scrollbar上修改一下:
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Scrollbar'),
          ),
          body: NotificationListener<OverscrollIndicatorNotification>(
            onNotification: (notification) {
              //滑动指示器是否在头部 true在前端,false在末端
              print('${notification.leading}');
              return true;
            },
            child: Scrollbar(
              radius: Radius.circular(10),
              thickness: 10,
              child: ListView.builder(
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text('item $index'),
                  );
                },
                itemCount: 30,
              ),
            ),
          ),
        );
      }
    
    • KeepAliveNotification:这个留意过列表复用的源码的话,例如ListView,就会知道addAutomaticKeepAlives就是使用这个来保存状态的

    6.自定义Notification

    这里我们做个简单的演示

          body: NotificationListener<_CustomNotification>(
            onNotification: (notification) {
              print('1 ${notification.msg}');
              return true;
            },
            child: NotificationListener<_CustomNotification>(
              onNotification: (notification) {
                print('2 ${notification.msg}');
                return true;
              },
              child: Builder(builder: (context) {
                return RaisedButton(
                  onPressed: () {
                    _CustomNotification('点击了Button').dispatch(context);
                  },
                  child: Text('RaisedButton'),
                );
              }),
            ),
          ),
    
    class _CustomNotification extends Notification {
      _CustomNotification(this.msg);
    
      final String msg;
    }
    
    image.png

    这里在2级NotificationListener处消费掉当前的通知了,所以不再向1级NotificationListener传递通知了,如果将2级NotificationListener处设置为false,则会传递

    image.png

    下一节:DraggableScrollableSheet、DraggableScrollableNotification

    Flutter(84):DraggableScrollableSheet、DraggableScrollableNotification

    Flutter教学目录持续更新中

    Github源代码持续更新中

    相关文章

      网友评论

        本文标题:Flutter(83):NotificationListener

        本文链接:https://www.haomeiwen.com/subject/snzmiktx.html