Flutter(81):Scroll组件之NestedScrollView

Flutter教学目录持续更新中

Github源代码持续更新中

1.NestedScrollView介绍

一个可以嵌套其它可滚动widget的widget

2.NestedScrollView属性

  • controller:ScrollController
  • scrollDirection = Axis.vertical:滑动方向
  • reverse = false:是否倒序
  • physics:控制用户滚动视图的交互
  • headerSliverBuilder:NestedScrollViewHeaderSliversBuilder
  • body:Widget

3.使用

  _mySliverAppBar() {
    return SliverAppBar(
      title: Text('NestedScrollView'),
      expandedHeight: 200,
      flexibleSpace: FlexibleSpaceBar(
        background: Image.network(
          ImageUrlConstant.imageUrl1,
          fit: BoxFit.cover,
        ),
        collapseMode: CollapseMode.parallax,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return [
          _mySliverAppBar(),
        ];
      },
      body: Container(
        color: Colors.blue,
      ),
    );
  }
image.png

NestedScrollView的头部需要sliver组件,但是body可以使用非sliver组件,这样它就可以支持在实现tab,page联动的效果,这是CustomScrollView无法提供的。

4.NestedScrollView的一些注意事项

NestedScrollView+ListView+SliverAppBar

  _mySliverAppBar() {
    return SliverAppBar(
      title: Text('NestedScrollView'),
      expandedHeight: 200,
      flexibleSpace: FlexibleSpaceBar(
        background: Image.network(
          ImageUrlConstant.imageUrl1,
          fit: BoxFit.cover,
        ),
        collapseMode: CollapseMode.parallax,
      ),
    );
  }

  _myItem(int index) {
    return Container(
      color: Colors.yellow,
      child: ListTile(
        title: Text('List $index'),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return [
            _mySliverAppBar(),
          ];
        },
        body: ListView.builder(
          itemBuilder: (BuildContext context, int index) {
            return _myItem(index);
          },
          itemCount: 15,
        ),
      ),
    );
  }
image.png

这种情况下ListView是无法得到准确的头部展开折叠高度的,那么flutter提供了解决方案:SliverOverlapAbsorber+SliverOverlapInjector

  _mySliverAppBar() {
    return SliverAppBar(
      title: Text('NestedScrollView'),
      expandedHeight: 200,
      flexibleSpace: FlexibleSpaceBar(
        background: Image.network(
          ImageUrlConstant.imageUrl1,
          fit: BoxFit.cover,
        ),
        collapseMode: CollapseMode.parallax,
      ),
    );
  }

  _myItem(int index) {
    return Container(
      color: Colors.yellow,
      child: ListTile(
        title: Text('List $index'),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return [
            SliverOverlapAbsorber(
              handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
              sliver: _mySliverAppBar(),
            )
          ];
        },
        body: Builder(
          builder: (context) {
            return CustomScrollView(
              slivers: [
                SliverOverlapInjector(
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                ),
                SliverList(
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                      return _myItem(index);
                    },
                    childCount: 15,
                  ),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
image.png

这里有个需要注意的地方,那就是NestedScrollView的body必须构建一个Builder,使用NestedScrollView的context去创建SliverOverlapInjector。

下一节:Scroll组件之Scrollbar

Flutter(82):Scroll组件之Scrollbar

Flutter教学目录持续更新中

Github源代码持续更新中

你可能感兴趣的:(Flutter(81):Scroll组件之NestedScrollView)