美文网首页Flutter圈子Flutter中文社区Flutter
Flutter 首页必用组件NestedScrollView

Flutter 首页必用组件NestedScrollView

作者: 老孟程序员 | 来源:发表于2020-05-08 08:15 被阅读0次

    老孟导读:昨天Flutter 1.17版本重磅发布,新的版本主要是优化性能、修复bug,有人觉得此版本毫无亮点,但也从另一方面体现了Flutter目前针对移动端已经较为完善,想了解具体内容,文末有链接,如果你想升级到最新版本,建议慎重,有些人升级后项目无法运行。
    今天介绍的组件是NestedScrollView,大部分的App首页都会用到这个组件。

    可以在其内部嵌套其他滚动视图的滚动视图,其滚动位置是固有链接的。

    在普通的ScrollView中, 如果有一个Sliver组件容纳了一个TabBarView,它沿相反的方向滚动(例如,允许用户在标签所代表的页面之间水平滑动,而列表则垂直滚动),则该TabBarView内部的任何列表都不会相互作用 与外部ScrollView。 例如,浏览内部列表以滚动到顶部不会导致外部ScrollView中的SliverAppBar折叠以展开。

    滚动隐藏AppBar

    比如实现如下场景,当列表滚动时,隐藏AppBar,用法如下:

    NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[SliverAppBar(
          title: Text('老孟'),
        )];
      },
      body: ListView.builder(itemBuilder: (BuildContext context,int index){
        return Container(
          height: 80,
          color: Colors.primaries[index % Colors.primaries.length],
          alignment: Alignment.center,
          child: Text(
            '$index',
            style: TextStyle(color: Colors.white, fontSize: 20),
          ),
        );
      },itemCount: 20,),
    )
    

    效果如下:

    SliverAppBar展开折叠

    用法如下:

    NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[SliverAppBar(
          expandedHeight: 230.0,
          pinned: true,
          flexibleSpace: FlexibleSpaceBar(
            title: Text('复仇者联盟'),
            background: Image.network(
              'http://img.haote.com/upload/20180918/2018091815372344164.jpg',
              fit: BoxFit.fitHeight,
            ),
          ),
        )];
      },
      body: ListView.builder(itemBuilder: (BuildContext context,int index){
        return Container(
          height: 80,
          color: Colors.primaries[index % Colors.primaries.length],
          alignment: Alignment.center,
          child: Text(
            '$index',
            style: TextStyle(color: Colors.white, fontSize: 20),
          ),
        );
      },itemCount: 20,),
    )
    

    效果如下:

    与TabBar配合使用

    用法如下:

    NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(
            expandedHeight: 230.0,
            pinned: true,
            flexibleSpace: Padding(
              padding: EdgeInsets.symmetric(vertical: 8),
              child: PageView(),
            ),
          ),
          SliverPersistentHeader(
            pinned: true,
            delegate: StickyTabBarDelegate(
              child: TabBar(
                labelColor: Colors.black,
                controller: this._tabController,
                tabs: <Widget>[
                  Tab(text: '资讯'),
                  Tab(text: '技术'),
                ],
              ),
            ),
          ),
        ];
      },
      body: TabBarView(
        controller: this._tabController,
        children: <Widget>[
          RefreshIndicator(
            onRefresh: (){
              print(('onRefresh'));
            },
            child: _buildTabNewsList(_newsKey, _newsList),
          ),
    
          _buildTabNewsList(_technologyKey, _technologyList),
        ],
      ),
    )
    

    StickyTabBarDelegate 代码如下:

    class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
      final TabBar child;
    
      StickyTabBarDelegate({@required this.child});
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return Container(
          color: Theme.of(context).backgroundColor,
          child: this.child,
        );
      }
    
      @override
      double get maxExtent => this.child.preferredSize.height;
    
      @override
      double get minExtent => this.child.preferredSize.height;
    
      @override
      bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
        return true;
      }
    }
    

    效果如下:

    其他属性

    通过scrollDirectionreverse参数控制其滚动方向,用法如下:

    NestedScrollView(
      scrollDirection: Axis.horizontal,
      reverse: true,
      ...
    )
    

    scrollDirection滚动方向,分为垂直和水平方向。

    reverse参数表示反转滚动方向,并不是由垂直转为水平,而是垂直方向滚动时,默认向下滚动,reverse设置false,滚动方向改为向上,同理水平滚动改为水平向左。

    controller为滚动控制器,可以监听滚到的位置,设置滚动的位置等,用法如下:

    _scrollController = ScrollController();
    
    //监听滚动位置
        _scrollController.addListener((){
          print('${_scrollController.position}');
        });
        //滚动到指定位置
        _scrollController.animateTo(20.0);
    
    CustomScrollView(
        controller: _scrollController,
        ...
    ) 
    

    physics表示可滚动组件的物理滚动特性,具体查看ScrollPhysics

    交流

    老孟Flutter博客地址(近200个控件用法):http://laomengit.com

    欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

    相关文章

      网友评论

        本文标题:Flutter 首页必用组件NestedScrollView

        本文链接:https://www.haomeiwen.com/subject/gvlxnhtx.html