Flutter CustomScrollView要點

在上篇文章中我們學了SingleChildScrollView這個滑動控件,現在我們學習一下CustomScrollView這個控件。

CustomScrollView這個控件是針對多個滾動佈局的組件,比如頂部一個GridView,底部又來一個ListView,而要求兩個界面具有聯動性,如果是單純的GridViewListView的話,這時候並不能保證一致的滑動性,比如,GridView滑動完ListView再進行滑動。這時候我們就需要一個膠水,把這些彼此獨立的可滾動組件起來,恰恰CustomScrollView就是膠水的角色。所以:CustomScrollView可以又多個滑動的組件,且它的子組件都是遵循Sliver(薄片)的功能,共用CustomScrollViewScrollable。一般的,這些組件差不多都是Sliver開頭,如:

SliverAppBar,
SliverPadding,
SliverFixedExtentList,
SliverList

等等。

如何區分一個子組件是否是Sliver

如果直接將ListView、GridView作爲CustomScrollView是不行的,因爲它們本身是可滾動組件而並不是Sliver!因此,爲了能讓可滾動組件能和CustomScrollView配合使用,Flutter提供了一些可滾動組件的Sliver版,如SliverList、SliverGrid等。實際上Sliver版的可滾動組件和非Sliver版的可滾動組件最大的區別就是前者不包含滾動模型(自身不能再滾動),而後者包含滾動模型

個人通俗一點理解就是:ListView、GridView這些組件本身已經是可滾動組件了,所以它們就不能再被嵌套在CustomScrollView中了。

而在CustomScrollView中的Sliver(薄片)組件多以Sliver開頭,如SliverAppBarSliverList等等。

下面引用一段CustomScrollView中含多個Sliver薄片的代碼,頁面。

import 'package:flutter/material.dart';

class CustomScrollViewTestRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //因爲本路由沒有使用Scaffold,爲了讓子級Widget(如Text)使用
    //Material Design 默認的樣式風格,我們使用Material作爲本路由的根。
    return Material(
      child: CustomScrollView(
        slivers: <Widget>[
          //AppBar,包含一個導航欄
          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) {
                  //創建子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) {
                  //創建列表項      
                  return new Container(
                    alignment: Alignment.center,
                    color: Colors.lightBlue[100 * (index % 9)],
                    child: new Text('list item $index'),
                  );
                },
                childCount: 50 //50個列表項
            ),
          ),
        ],
      ),
    );
  }
}

試着跑一下?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章