[Flutter]NotificationListener滑动事件分发

什么是NotificationListener

字面意思是通知监听器,通知基本等价于Android中的事件,所以通知听就可以类比成Android中的事件分发机制。但与Android中任何View都可以处理事件分发不同,Flutter中只有Notification可以监听到通知。所以,当需要对某组件进行通知 监听时,需要用NotificationListener将组件包起来。
怎么又是包起来,在Android中处理事件分发不都是要自定义View吗?实际上Flutter中处处都是自定义Widget,只不过大多数不是通过继承的方式,而是组合。可能仅仅是简简单单的Container包含一个Text,这也算的上是自定义Widget。而当我们给自己的Widget树包裹一层NotificationListener,它就是一个能够处理通知监听的新的Widget了。Compose

支持监听哪些通知

Notification的子类

滑动通知

通知在Flutter中的抽象为Notification类,它包含12个子类,对应12种通知,下面将介绍跟主题相关的滑动通知ScrollNotification。滑动通知ScrollNotification有如图五个子类,它们分别代表五种滑动通知,滑动组件触发相应滑动事件时,向Ancestor的NotificationListener发送通知。
滑动通知子类
滑一滑,看一看,找一找。看看能不能在滑动过程中找到这几个通知。

 NotificationListener(
      onNotification: (ScrollNotification notification) {
   //收到Notification
        setState(() {
   
          _currentNotification = notification.runtimeType.toString();//将notification实例的类名展示
        });
        print(notification.runtimeType.toString());//同时输出log
        return true;
      },
      child: Stack(
        children: <Widget>[
          ListView.builder(
            //...省略
          ),
          Center(child: Text('$_currentNotification'))
        ],
      ),
    );

滑动

找到了,全找到了,ScrollStartNotification–ScrollUpdateNotification–OverScrollNotification–UserScrollNotification–EndScrollNotification,但是有一个疑问,按常理来说,滑动结束时就应该是EndScroll,而实际结果却是UserScroll,当在原地点击的时候,松手时才是EndScroll。于是,看看Log的输出结果吧:
滑动过程中的Log
似乎疑惑可以解开了,在滑动结束时,实际上收到了EndScrollNotification,但是被紧跟其后的UserScrollNotification覆盖掉了。通过观察,发现规律,每次滑动的方向发生改变时,就会产生UserScroll事件。而点击过程中的Log也印证了这一点,End前为无方向,End后为无方向,故不会产生UserScroll。

几种滑动通知对应的事件

ScrollStartNotification

当滑动组件开始滑动时,实际上手指接触屏幕那一刻就会触发。

ScrollEndNotification

滑动组件结束滑动时

ScrollUpdateNotification

组件产生位移时

OverscrollNotification

滑动越界时

UserScrollNotification

滑动方向发生改变时

主要属性onNotification(Notification)

来看一下NotificationListener的事件分发源码
源码
可见,分发一个通知有两个条件,一是通知非空,二是通知的类型为T,原来NotificationListener可以指定泛型,这样onNotification方法只会接收到对应事件的回调,不如下面一段代码只会收到滑动结束的通知。

NotificationListener<ScrollEndNotification>(
      onNotification: (ScrollNotification notification) {
   
        return 
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Flutter的TabBarView是一个非常方便的组件,用于在不同的选项卡之间切换,并且可以包含滚动视图。如果你想在左右滑动时执行一些自定义代码,可以使用GestureDetector来监听水平拖动手势。 以下是一个简单的示例代码,它演示了如何在TabBarView中添加水平滑动手势监听器。 ```dart class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin { TabController _tabController; @override void initState() { super.initState(); _tabController = TabController(vsync: this, length: 3); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), bottom: TabBar( controller: _tabController, tabs: [ Tab(text: 'Tab 1'), Tab(text: 'Tab 2'), Tab(text: 'Tab 3'), ], ), ), body: GestureDetector( onHorizontalDragEnd: (details) { if (details.primaryVelocity < 0) { // Swiped left, switch to the next tab _tabController.animateTo(_tabController.index + 1); } else if (details.primaryVelocity > 0) { // Swiped right, switch to the previous tab _tabController.animateTo(_tabController.index - 1); } }, child: TabBarView( controller: _tabController, children: [ Container(color: Colors.red), Container(color: Colors.green), Container(color: Colors.blue), ], ), ), ); } @override void dispose() { _tabController.dispose(); super.dispose(); } } ``` 在这个示例中,我们将GestureDetector添加到TabBarView的外部,并将其与onHorizontalDragEnd回调绑定。当用户水平滑动时,我们检查primaryVelocity属性的值,以确定用户是向左还是向右滑动。然后,我们使用TabController来切换到下一个或上一个选项卡。 注意,我们还需要在State对象的dispose方法中调用TabController的dispose方法来释放资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值