flutter ScrollController

ScrollController

/* 监听滚动的事件

对于滚动的视图我们需要监听它的一些滚动事件、在监听到的时候去做一些操作。
- 比如滚动到底部、我们希望可以做下拉刷新更多
- 比如滚动到一定位置时显示一个回到顶部的按钮、点击回到顶部的按钮、回到顶部。
- 比如监听滚动什么时候开始、什么时候结束。

在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 来监听滚动事件。
*/
class Content1 extends StatefulWidget {
  @override
  _Content1State createState() => _Content1State();
}

class _Content1State extends State<Content1> {
  ScrollController _scrollController = ScrollController();
  bool _isScrollTop = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    // 初始化ScrollController

    // 监听滚动
    _scrollController.addListener(() {
      print('_scrollController.addListener: ${_scrollController.offset}');
      var temp = _scrollController.offset >= 1000;
      if (temp != _isScrollTop) {
        setState(() {
          _isScrollTop = temp;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ScrollController'),
      ),
      body: ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text('item$index'),
          );
        },
        itemCount: 100, // 最大的数量
        itemExtent: 60, // 每条的高度
        controller: _scrollController, // 监听的控制器
      ),
      floatingActionButton: !_isScrollTop
          ? null
          : FloatingActionButton(
              child: Icon(Icons.arrow_upward),
              onPressed: () {
                print('click-FloatingActionButton');
                //_scrollController.jumpTo(0);
                _scrollController.animateTo(0,
                    duration: Duration(milliseconds: 1000), curve: Curves.ease);
              },
            ),
    );
  }
}

[Flutter-25] ScrollController 监听滚动一_ico