Flutter 中 NestedScrollView 和 SliverAppBar 的使用

如今在 App 中,常見的一個效果就是摺疊工具欄,在 Android 上,這種效果能夠經過 CollapsingToolbarLayout + NestedScrollView + AppBarLayout 來實現,在 Flutter 裏面,也有 NestedScrollView 和 SliverAppBar 來實現這樣的效果。git

1、只使用 AppBar

先看最簡單的狀況,只使用 AppBargithub

通常狀況下,咱們的 App 都是這樣的:編程

return  Scaffold(
       appBar: AppBar(
         title: Text("標題"),
       ),
       body: ListView.builder(
         itemBuilder: (BuildContext context, int index) {
           return ListTile(title:Text( "標題$index"),);
         },
         itemCount: 50,
       ),

);
複製代碼

效果是這樣的:bash

2、使用 SliverAppBar

SliverAppBar 實際上是屬於 Slivers 裏面的一個控件,而 Slivers 包含的可滾動的控件通常都是在複雜的滑動嵌套的場景下使用,通常都是做爲 CustomScrollView 的子 Widget 來使用。好比 ListView 對應的 Slivers 組件是 SliverFixedExtentList,GirdView 對應的是 SliverGrid。CustomScrollView 的做用就是使這些 Sliver 組件的滑動效果同一的。微信

若是是使用 NestedScrollView + SliverAppbar 是這樣的:app

return  Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
              SliverAppBar(
            title: Text("標題"),
            floating: false,
            snap: false,
            pinned: true,
          )

          ];
        },
        body: ListView.builder(
          itemBuilder: (BuildContext context, int index) {
            return ListTile(title:Text( "標題$index"),);
          },
          itemCount: 50,
        ),
      ),
      
    );
複製代碼

效果:工具

效果其實和上面的同樣。flex

接着把 pined 屬性值改成 false 。效果以下:ui

也就是 pinned 這個屬性能夠控制 AppBar 是否固定。

其餘屬性以下:this

const SliverAppBar({
    Key key,
    this.leading,         //在標題左側顯示的一個控件,一般爲一個圖標
    this.automaticallyImplyLeading = true,//? 控制是否應該嘗試暗示前導小部件爲null
    this.title,           //標題
    this.actions,          //右側的操做菜單,最多三個
    this.flexibleSpace,    //能夠展開的區域,一般是一個FlexibleSpaceBar
    this.bottom,         //底部內容區域,一般是 TabBar
    this.elevation,            //陰影
    this.forceElevated = false, 
    this.backgroundColor,       //APP bar 的顏色,默認值爲 ThemeData.primaryColor
    this.brightness,   //Appbar的主題,有白色和黑色兩種主題
    this.iconTheme,  //Appbar 上圖標的顏色、透明度、和尺寸信息
    this.textTheme,    //Appbar 上的文字主題
    this.primary = true,  //此應用欄是否顯示在屏幕頂部
    this.centerTitle,     //標題是否居中顯示,默認值根據不一樣的操做系統
    this.titleSpacing = NavigationToolbar.kMiddleSpacing,//橫軸上標題內容 周圍的間距
    this.expandedHeight,     //展開高度
    this.floating = false,       //是否隨着滑動隱藏標題
    this.pinned = false,  //是否固定在頂部
    this.snap = false,   //與floating結合使用
  })
複製代碼

3、摺疊工具欄

指定 flexibleSpace 就能夠定義展開區域。

return  Scaffold(
     body: NestedScrollView(
       headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
         return <Widget>[


          /*   SliverAppBar(
           title: Text("標題"),
           floating: false,
           snap: false,
           pinned: true,
         )
*/


           SliverAppBar(
             expandedHeight: 200.0,
             floating: true,
             snap: false,
             pinned: true,
             flexibleSpace: FlexibleSpaceBar(
                 centerTitle: true,
                 title: Text("標題",
                     style: TextStyle(
                       color: Colors.redAccent,
                       fontSize: 16.0,
                     )),
                 background: Image.asset(
                   "images/bg.jpg",
                   fit: BoxFit.fill,
                 )
             ),
           )


         ];
       },
       body: ListView.builder(
         itemBuilder: (BuildContext context, int index) {
           return ListTile(title:Text( "標題$index"),);
         },
         itemCount: 50,
       ),
     ),

   );

複製代碼

效果:

4、工具欄底部加 Tab

SliverBar 中指定 bottom 屬性爲 TabBar,同時 NestedScrollView body 屬性指定爲 TabVarView

return Scaffold(
      body: NestedScrollView(
          controller: _scrollviewController,
          headerSliverBuilder: (context, boxIsScrolled) {

            return [
              SliverAppBar(
                pinned: true,
                floating: true,
                elevation: 0.5,
                forceElevated: true,
                //backgroundColor: Colors.grey,
                expandedHeight: 240,
                flexibleSpace: FlexibleSpaceBar(
                  collapseMode: CollapseMode.pin, //視差效果
                  background: Container(
                    //color: Colors.grey,
                    child: Column(
                      children: <Widget>[
                        Container(
                          height: 210.0,
                          width: 420,
                          color: Colors.blue,
                          child: Image.asset(
                            "images/bg.jpg",
                            fit: BoxFit.fitWidth,
                          ),
                        )
                      ],
                    ),
                  ),
                ),
                bottom: TabBar(controller: _tabController, tabs: [
                  Tab(
                    text: "首頁",
                  ),
                  Tab(
                    text: "消息",
                  ),
                  Tab(
                    text: "購物",
                  ),
                  Tab(
                    text: "個人",
                  )
                ]),
              ),



            ];

          },

          body: TabBarView(
              controller: _tabController,
              children: [
                Center(
                  child:  Text("one"),
                ),

                Center(
                  child:  Text("two"),
                ),

                Center(
                  child:  Text("three"),
                ),

                Center(
                  child:  Text("four"),
                ),

              ]

          )
      ),
    );
複製代碼

效果:

github

最後

歡迎關注「Flutter 編程開發」微信公衆號 。

相關文章
相關標籤/搜索