Flutter 首頁必用組件NestedScrollView

老孟導讀:昨天Flutter 1.17版本重磅發佈,新的版本主要是優化性能、修復bug,有人以爲此版本毫無亮點,但也從另外一方面體現了Flutter目前針對移動端已經較爲完善,想了解具體內容,文末有連接,若是你想升級到最新版本,建議慎重,有些人升級後項目沒法運行。
今天介紹的組件是NestedScrollView,大部分的App首頁都會用到這個組件。html

能夠在其內部嵌套其餘滾動視圖的滾動視圖,其滾動位置是固有連接的。git

在普通的ScrollView中, 若是有一個Sliver組件容納了一個TabBarView,它沿相反的方向滾動(例如,容許用戶在標籤所表明的頁面之間水平滑動,而列表則垂直滾動),則該TabBarView內部的任何列表都不會相互做用 與外部ScrollView。 例如,瀏覽內部列表以滾動到頂部不會致使外部ScrollView中的SliverAppBar摺疊以展開。微信

滾動隱藏AppBar

好比實現以下場景,當列表滾動時,隱藏AppBar,用法以下:app

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,),
)

效果以下:ide

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,),
)

效果以下:flex

與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 代碼以下:ui

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;
  }
}

效果以下:this

其餘屬性

經過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】:

相關文章
相關標籤/搜索