【Flutter 2-12】Flutter手把手教程UI布局和Widget——網(wǎng)格列表GridView

作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)

GridView

GridView 是一個好用的網(wǎng)格布局控件,它的很多屬性跟前面提到的ListView是一樣的,重復的屬性這里就不贅述了。我們重點了解初始化方法GridView.count的使用,還有兩個代理SliverGridDelegateWithFixedCrossAxisCountSliverGridDelegateWithMaxCrossAxisExtent的參數(shù)以及使用。

GridView.count

我們先來看GridView.count的構(gòu)造函數(shù)

GridView.count({
    /// key 
    Key key,
    /// 布局方向
    Axis scrollDirection = Axis.vertical,
    /// 是否 倒序顯示
    bool reverse = false,
    /// ScrollController用于控制滾動位置和監(jiān)聽滾動事件
    ScrollController controller,
    /// 是否使用默認的controller
    bool primary,
    /// 滾動效果  可以通過此參數(shù) 設置 GridView 不可滾動
    ScrollPhysics physics,
    /// 是否根據(jù)子控件的總長度來設置 GridView 的長度,默認值為false
    bool shrinkWrap = false,
    ///  padding
    EdgeInsetsGeometry padding,
    /// 交叉軸 子控件的個數(shù)
    @required int crossAxisCount,
    /// 主軸方向的間距
    double mainAxisSpacing = 0.0,
    /// 交叉軸方向子元素的間距
    double crossAxisSpacing = 0.0,
    /// 子控件的寬高比例
    double childAspectRatio = 1.0,
    // 在 關(guān)閉屏幕時 是否釋放子控件
    bool addAutomaticKeepAlives = true,
    /// 是否 避免列表項重繪
    bool addRepaintBoundaries = true,
    /// 該屬性表示是否把子控件包裝在IndexedSemantics里,用來提供無障礙語義
    bool addSemanticIndexes = true,
    // 預加載子控件的個數(shù)
    double cacheExtent,
    /// 子控件的數(shù)組
    List<Widget> children = const <Widget>[],
    /// 子控件的數(shù)量
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
    ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
})

這里要說的是有兩個比較重要的參數(shù)crossAxisSpacingchildAspectRatio,這個兩個參數(shù)是用來定義子控件大小的。

假如我們設置 crossAxisSpacing = 2,那么每一行就會顯示2個控件,而且控件的高度由childAspectRatio來確定。
childAspectRatio表示子控件的寬高比,假如我們設置為2 / 3,那么高就是寬的1.5倍,這樣就可以計算子控件的大小了,并且按照 GridView設置好的方向來排列和布局子控件。

GridView.count(
    crossAxisCount: 3,
    childAspectRatio: 2 / 3,
    children: List.generate(
        50,
        (index) {
        return Card(
            child: Container(
            color: Colors.green,
                child: Center(
                    child: Text("$index"),
                ),
            ),
        );
        },
    ),
)

效果圖如下:

2021_01_16_gridview_count

SliverGridDelegateWithFixedCrossAxisCount

除了GridView.count()這種構(gòu)造方法,我們很多時候常用一個構(gòu)造方法是GridView.builder(gridDelegate: itemBuilder:),它接收一個delegate對象,并且跟ListView一樣接收一個itemBuilder方法。
SliverGridDelegateWithFixedCrossAxisCount的構(gòu)造方法如下:

SliverGridDelegateWithFixedCrossAxisCount({
  @required this.crossAxisCount,
  this.mainAxisSpacing = 0.0,
  this.crossAxisSpacing = 0.0,
  this.childAspectRatio = 1.0,
})

可以看得出來它是把GridView.count()的幾個參數(shù)封裝了一下,具體的用法和效果跟GridView.count()一樣,這里就不贅述了。

SliverGridDelegateWithFixedCrossAxisCount在很多情況下都能滿足我們的布局需求,但是有一個不足,因為它設置的每一行數(shù)是一個定值。
當我們把屏幕旋轉(zhuǎn),此時原來的高度會變?yōu)楝F(xiàn)在的寬度,效果就會如下:

2021_01_16_gridview_la

所以我們可以使用下面delegate來解決這個問題。

SliverGridDelegateWithMaxCrossAxisExtent

我們可以在GridView.builder(gridDelegate: itemBuilder:)方法內(nèi)傳入另外一個參數(shù)SliverGridDelegateWithMaxCrossAxisExtent

構(gòu)造方法如下:

const SliverGridDelegateWithMaxCrossAxisExtent({
    @required this.maxCrossAxisExtent,
    this.mainAxisSpacing = 0.0,
    this.crossAxisSpacing = 0.0,
    this.childAspectRatio = 1.0,
}) 

這里有一個比較重要的參數(shù)就是maxCrossAxisExtent,這個值表示的是子控件最大的寬度是多少。
舉個例子:
手機的屏幕寬度為375,子控件之間的間距為0,maxCrossAxisExtent的值設置為100,那么我們知道子控件的寬度取值區(qū)間在0~100之間。

  • 假設我們布局3個子控件,3 乘以最大值100等于300,很明顯是不能滿足布局在375的寬度上的。
  • 假設我們布局4個子控件,4乘以100等于400,400 大于 375。我們知道寬度的取值區(qū)間在0~100,375 / 4 = 93.75既滿足了寬度小于100,又滿足了可以充滿375的寬度,那么子控件的個數(shù)為 4寬度為93.75

這就是maxCrossAxisExtent的用法。

其實GridView還可以做瀑布流效果,感興趣的同學可以去查一下。

想體驗以上的示例的運行效果,可以到我的Github倉庫項目flutter_app->lib->routes->gridview_page.dart查看,并且可以下載下來運行并體驗。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容