【问题标题】:ScrollController how can I detect Scroll start, stop and scrolling?ScrollController 如何检测滚动开始、停止和滚动?
【发布时间】:2019-05-10 06:13:46
【问题描述】:

我将 ScrollController 用于 SingleChildScrollView 小部件,我想检测滚动开始、结束/停止和仍在滚动的时间?

如何检测,我正在使用Listene

scrollController = ScrollController()
      ..addListener(() {
        scrollOffset = _scrollController.offset;
      });

也尝试使用_scrollController.position.activity.velocity,但没有帮助我。

还有

_scrollController.position.didEndScroll();
_scrollController.position.didStartScroll();

但是我该如何使用它呢?

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    从此链接 https://medium.com/@diegoveloper/flutter-lets-know-the-scrollcontroller-and-scrollnotification-652b2685a4ac

    只需将您的 SingleChildScrollView 包装到 NotificationListener 并更新您的代码,如 ..

    NotificationListener<ScrollNotification>(
                    onNotification: (scrollNotification) {
                      if (scrollNotification is ScrollStartNotification) {
                        _onStartScroll(scrollNotification.metrics);
                      } else if (scrollNotification is ScrollUpdateNotification) {
                        _onUpdateScroll(scrollNotification.metrics);
                      } else if (scrollNotification is ScrollEndNotification) {
                        _onEndScroll(scrollNotification.metrics);
                      }
                    },
                    child: SingleChildScrollView(
                    /// YOUR OWN CODE HERE
                   )
    )
    

    然后声明方法就像

    _onStartScroll(ScrollMetrics metrics) {
        print("Scroll Start");
      }
    
      _onUpdateScroll(ScrollMetrics metrics) {
        print("Scroll Update");
      }
    
      _onEndScroll(ScrollMetrics metrics) {
        print("Scroll End");
      }
    

    您将通过特定方式收到通知。

    【讨论】:

    【解决方案2】:

    不需要NotificationListener,我们可以单独使用滚动控制器。

    首先,使用WidgetsBinding.instance.addPostFrameCallback 注册一个帧后回调,以确保此时滚动控制器已经与滚动视图相关联。我们将在该回调中设置监听器。

    我们可以使用scrollController.addListener来收听滚动更新。

    为了收听开始和停止滚动,我们可以使用bgScrollCtrl.position.isScrollingNotifier.addListener。您可以查看以下代码:

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          scrollCtrl.addListener(() { 
            print('scrolling');
          });
          scrollCtrl.position.isScrollingNotifier.addListener(() { 
            if(!scrollCtrl.position.isScrollingNotifier.value) {
              print('scroll is stopped');
            } else {
              print('scroll is started');
            }
          });
        });
    

    【讨论】:

    • 比接受的答案更好的方法。谢谢。
    【解决方案3】:
    _scrollController.position.pixels
    
    if(_scrollController.position.pixels == _scrollController.position.maxScrollExtent){
    //scroll end
    }
    

    要使用这些,你应该在你的滚动视图中添加一个监听器

    【讨论】:

    • 谢谢,但我想检测滚动开始和停止。您只检测到滚动的结尾。我的错误让我更新了问题
    • 你可以使用 position.pixels
    • 你怎么给我例子
    • 如果 position.pixels 大于 minScrollExtent 然后滚动开始
    • 这就是我想要的,简短而准确。谢谢分享! :)
    【解决方案4】:

    NotificationListner 对我不起作用,因为我为滚动视图设置动画。当我触摸它时,会调用 ScrollEndNotification

    所以要检测滚动视图到达底部或顶部。我将 Listner 添加到滚动控制器。

      _scrollController.addListener(_scrollListener);
    
      _scrollListener() {
        if (_scrollController.offset >= _scrollController.position.maxScrollExtent &&
            !_scrollController.position.outOfRange) {
          setState(() {
            debugPrint("reach the top");
          });
        }
        if (_scrollController.offset <= _scrollController.position.minScrollExtent &&
            !_scrollController.position.outOfRange) {
          setState(() {
            debugPrint("reach the top");
          });
        }
      }
    

    【讨论】:

    • 这是滚动列表的结尾。不结束滚动动作
    【解决方案5】:

    您可以使用_scrollController.position.pixels 获取滚动位置,使用addlistener 获取更改通知

    if(_scrollController.position.pixels == _scrollController.position.maxScrollExtent){
    //for scroll end
    }
    
    if(_scrollController.position.pixels == _scrollController.position.minScrollExtent){
    //for scroll at top
    }
    

    【讨论】:

      【解决方案6】:

      这个用例有一个包。 scroll_edge_listener

      您可以使用一些配置(例如偏移和去抖动)来检测滚动的开始或结束。只需用 ScrollEdgeListener 包裹你的滚动视图并附加一个监听器。

      ScrollEdgeListener(
        edge: ScrollEdge.end,
        edgeOffset: 400,
        continuous: false,
        debounce: const Duration(milliseconds: 500),
        dispatch: true,
        listener: () {
          debugPrint('listener called');
        },
        child: ListView(
          children: const [
            Placeholder(),
            Placeholder(),
            Placeholder(),
            Placeholder(),
          ],
        ),
      ),
      
      

      【讨论】:

        猜你喜欢
        • 2018-06-26
        • 1970-01-01
        • 2016-01-31
        • 2020-03-10
        • 2012-03-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-01
        • 1970-01-01
        相关资源
        最近更新 更多