25.Flutter的ListView监听滚动事件之Scroll

2020-06-10  本文已影响0人  凯司机

对于滚动的视图,我们经常需要监听它的一些滚动事件,在监听到的时候去做对应的一些事情。

比如视图滚动到底部时,我们可能希望做上拉加载更多;

比如滚动到一定位置时显示一个回到顶部的按钮,点击回到顶部的按钮,回到顶部;

比如监听滚动什么时候开始,什么时候结束;

在Flutter中监听滚动相关的内容由两部分组成:ScrollController和ScrollNotification。

ScrollController

在Flutter中,Widget并不是最终渲染到屏幕上的元素(真正渲染的是RenderObject),因此通常这种监听事件以及相关的信息并不能直接从Widget中获取,而是必须通过对应的Widget的Controller来实现。

ListView、GridView的组件控制器是ScrollController,我们可以通过它来获取视图的滚动信息,并且可以调用里面的方法来更新视图的滚动位置。

另外,通常情况下,我们会根据滚动的位置来改变一些Widget的状态信息,所以ScrollController通常会和StatefulWidget一起来使用,并且会在其中控制它的初始化、监听、销毁等事件。

我们来做一个案例,当滚动到1000位置的时候,显示一个回到顶部的按钮:

jumpTo(double offset)、animateTo(double offset,...):这两个方法用于跳转到指定的位置,它们不同之处在于,后者在跳转时会执行一个动画,而前者不会。

ScrollController间接继承自Listenable,我们可以根据ScrollController来监听滚动事件。

classMyHomePageextendsStatefulWidget{

  @override

  State<StatefulWidget> createState() => MyHomePageState();

}

classMyHomePageStateextendsState{

  ScrollController _controller;

  bool _isShowTop = false;

  @override

  void initState() {

    // 初始化ScrollController

    _controller = ScrollController();

    // 监听滚动

    _controller.addListener(() {

      var tempSsShowTop = _controller.offset >= 1000;

      if (tempSsShowTop != _isShowTop) {

        setState(() {

          _isShowTop = tempSsShowTop;

        });

      }

    });

    super.initState();

  }

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text("ListView展示"),

      ),

      body: ListView.builder(

        itemCount: 100,

        itemExtent: 60,

        controller: _controller,

        itemBuilder: (BuildContext context, int index) {

          return ListTile(title: Text("item$index"));

        }

      ),

      floatingActionButton: !_isShowTop ? null : FloatingActionButton(

        child: Icon(Icons.arrow_upward),

        onPressed: () {

          _controller.animateTo(0, duration: Duration(milliseconds: 1000), curve: Curves.ease);

        },

      ),

    );

  }

}

上一篇下一篇

猜你喜欢

热点阅读