Flutter實戰(zhàn) CustomScrollView

2021-03-08 11:30 更新

CustomScrollView是可以使用 Sliver 來自定義滾動模型(效果)的組件。它可以包含多種滾動模型,舉個例子,假設(shè)有一個頁面,頂部需要一個GridView,底部需要一個ListView,而要求整個頁面的滑動效果是統(tǒng)一的,即它們看起來是一個整體。如果使用GridView+ListView來實現(xiàn)的話,就不能保證一致的滑動效果,因為它們的滾動效果是分離的,所以這時就需要一個"膠水",把這些彼此獨(dú)立的可滾動組件"粘"起來,而CustomScrollView的功能就相當(dāng)于“膠水”。

#可滾動組件的Sliver版

Sliver 在前面講過,有細(xì)片、薄片之意,在 Flutter 中,Sliver 通常指可滾動組件子元素(就像一個個薄片一樣)。但是在CustomScrollView中,需要粘起來的可滾動組件就是CustomScrollView的Sliver了,如果直接將ListView、GridView作為CustomScrollView是不行的,因為它們本身是可滾動組件而并不是 Sliver!因此,為了能讓可滾動組件能和CustomScrollView配合使用,F(xiàn)lutter 提供了一些可滾動組件的 Sliver 版,如 SliverList、SliverGrid 等。實際上 Sliver 版的可滾動組件和非Sliver版的可滾動組件最大的區(qū)別就是前者不包含滾動模型(自身不能再滾動),而后者包含滾動模型 ,也正因如此,CustomScrollView才可以將多個 Sliver"粘"在一起,這些 Sliver 共用CustomScrollViewScrollable,所以最終才實現(xiàn)了統(tǒng)一的滑動效果。

Sliver 系列 Widget 比較多,我們不會一一介紹,讀者只需記住它的特點(diǎn),需要時再去查看文檔即可。上面之所以說“大多數(shù)”Sliver 都和可滾動組件對應(yīng),是由于還有一些如 SliverPadding、 SliverAppBar 等是和可滾動組件無關(guān)的,它們主要是為了結(jié)合 CustomScrollView 一起使用,這是因為CustomScrollView 的子組件必須都是 Sliver。

#示例

import 'package:flutter/material.dart';


class CustomScrollViewTestRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //因為本路由沒有使用Scaffold,為了讓子級Widget(如Text)使用
    //Material Design 默認(rèn)的樣式風(fēng)格,我們使用Material作為本路由的根。
    return Material(
      child: CustomScrollView(
        slivers: <Widget>[
          //AppBar,包含一個導(dǎo)航欄
          SliverAppBar(
            pinned: true,
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: const Text('Demo'),
              background: Image.asset(
                "./images/avatar.png", fit: BoxFit.cover,),
            ),
          ),


          SliverPadding(
            padding: const EdgeInsets.all(8.0),
            sliver: new SliverGrid( //Grid
              gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2, //Grid按兩列顯示
                mainAxisSpacing: 10.0,
                crossAxisSpacing: 10.0,
                childAspectRatio: 4.0,
              ),
              delegate: new SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  //創(chuàng)建子widget      
                  return new Container(
                    alignment: Alignment.center,
                    color: Colors.cyan[100 * (index % 9)],
                    child: new Text('grid item $index'),
                  );
                },
                childCount: 20,
              ),
            ),
          ),
          //List
          new SliverFixedExtentList(
            itemExtent: 50.0,
            delegate: new SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  //創(chuàng)建列表項      
                  return new Container(
                    alignment: Alignment.center,
                    color: Colors.lightBlue[100 * (index % 9)],
                    child: new Text('list item $index'),
                  );
                },
                childCount: 50 //50個列表項
            ),
          ),
        ],
      ),
    );
  }
}

代碼分為三部分:

  • 頭部SliverAppBarSliverAppBar對應(yīng)AppBar,兩者不同之處在于SliverAppBar可以集成到CustomScrollViewSliverAppBar可以結(jié)合FlexibleSpaceBar實現(xiàn) Material Design 中頭部伸縮的模型,具體效果,讀者可以運(yùn)行該示例查看。
  • 中間的SliverGrid:它用SliverPadding包裹以給SliverGrid添加補(bǔ)白。SliverGrid是一個兩列,寬高比為4的網(wǎng)格,它有20個子組件。
  • 底部SliverFixedExtentList:它是一個所有子元素高度都為50像素的列表。

運(yùn)行效果如圖:

圖6-12

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號