flutter在包含ListVIew的滚动列表页面中监听手势:NotificationListener

列表控件内部页有监听事件,使用GestureDetector监听有冲突,所以使用NotificationListener。

示例中增加了Listener监听手指滑动方向

dart 复制代码
//手指的偏移量
  double _startDx = 0.0;
  double _endDx = 0.0;
  double _dy = 0.0;
  //标签栏高度
  double _tabBarHeight = 80.w;
  //标签栏刷新事件
  late StateSetter _setTabBarState;
  //偏移阈值
  double _listerOffsetThreshold = 40.0;

_body() {
    return NotificationListener<ScrollNotification>(
        onNotification: (dynamic scrollNotification) {
          if (scrollNotification is ScrollUpdateNotification &&
              scrollNotification.depth == 0) {
            // 滚动且是列表滚动的时候
            //  print('滑动偏移量:${scrollNotification.metrics.pixels}');
          }
          return true;
        },
      child: Listener(
          onPointerDown: (downPointer){
            _startDx = downPointer.position.dx;
            _dy = downPointer.position.dy;
          },
          onPointerMove: _onPointerMove,
          onPointerUp: _onPointerUp,
        child: Column(
          children: [
            // 头部分类列表
            _userShareTabBar(),
            // 推享文章列表
            Expand(
            child: ListView.builder(
            /// 列表
            )
            ),
          ],
        )
      )
    );
  }

_onPointerMove(PointerMoveEvent movePointer){
    //向下滑动。
    if (movePointer.position.dy - _dy > 0) {
      if (movePointer.position.dy - _dy > _listerOffsetThreshold) {
        print('向下滑动');
        _setTabBarState((){
          _tabBarHeight = 80.w;
        });
      }
    } else {
      if (-(movePointer.position.dy - _dy) > _listerOffsetThreshold) {
        print('向上滑动');
        _setTabBarState((){
          _tabBarHeight = 0.0;
        });
      }
    }
  }

  _onPointerUp(PointerUpEvent upPointer){
    _endDx = upPointer.position.dx;
    //向下滑动
    if (upPointer.position.dy - _dy > 0) {
      if (upPointer.position.dy - _dy > _listerOffsetThreshold) {
        print('向下滑动');
        _setTabBarState((){
          _tabBarHeight = 80.w;
        });
      }
    } else {
      if (-(upPointer.position.dy - _dy) > _listerOffsetThreshold) {
        print('向上滑动');
        _setTabBarState((){
          _tabBarHeight = 0.0;
        });
      }
    }

    final double _deltaX = _endDx - _startDx;
    if(_deltaX.abs() > _listerOffsetThreshold){
      if(_tabBarHeight == 0.0){
        _setTabBarState((){
          _tabBarHeight = 80.w;
        });
      }
    }
  }

//在当前页面中需要局部刷新的模块
_userShareTabBar() {
    //使用StatefulBuilder在手势监听事件中调用局部的刷新(使用setState会刷新整个页面造成卡顿)
    return StatefulBuilder(
        builder: (context, setStateBuilder) {
          _setTabBarState = setStateBuilder;
          return AnimatedContainer(
              duration: Duration(milliseconds: 200),
              height: _tabBarHeight,
              child: UserShareTabBarPage()
          );
        });
  }
相关推荐
消失的旧时光-194311 小时前
Flutter 组件:Row / Column
flutter
程序员老刘14 小时前
Flutter版本选择指南:3.35稳定,3.38发布 | 2025年11月
flutter·客户端
kirk_wang15 小时前
Flutter 3.38和Dart 3.10中最大的更新
flutter
前端小伙计16 小时前
Flutter 配置国内镜像,加速项目加载!
flutter
zonda的地盘19 小时前
开发 Flutter Plugin 之 初始配置
flutter
消失的旧时光-19432 天前
Flutter TextField 从入门到精通:掌握输入框的完整指南
flutter
wordbaby2 天前
Flutter Form Builder 完全指南:告别 Controller 地狱
前端·flutter
tbit2 天前
fluwx 拉起小程序WXLog:Error:fail to load Keychain status:-25300, keyData null:1
flutter·ios·微信小程序
QuantumLeap丶2 天前
《Flutter全栈开发实战指南:从零到高级》- 19 -手势识别
flutter·ios·前端框架
卢叁2 天前
Flutter之阿里云视频播放器支持 iOS模拟器解决方案
flutter