【Flutter 2-11】Flutter手把手教程UI佈局和Widget——列表ListView
作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)
ListView
ListView
是在移動端非常常見的控制元件,在大多數的展示場景中都離不開ListView
。在Flutter
中對ListView
的封裝也非常好,簡單幾行程式碼就可以滿足我們佈局一個滾動列表的需求。
先來看一下建構函式:
ListView({ /// key Key key, /// 佈局方向 Axis scrollDirection = Axis.vertical, /// 是否 倒序顯示 bool reverse = false, /// ScrollController用於控制滾動位置和監聽滾動事件 ScrollController controller, /// 是否使用預設的controller bool primary, /// 滾動效果 可以通過此引數 設定 ListView 不可滾動 ScrollPhysics physics, /// 是否根據子控制元件的總長度來設定ListView的長度,預設值為false bool shrinkWrap = false, /// padding EdgeInsetsGeometry padding, /// 子控制元件高度 this.itemExtent, // 在 關閉螢幕時 是否釋放子控制元件 bool addAutomaticKeepAlives = true, /// 是否 避免列表項重繪 bool addRepaintBoundaries = true, /// 該屬性表示是否把子控制元件包裝在IndexedSemantics裡,用來提供無障礙語義 bool addSemanticIndexes = true, // 預載入子控制元件的個數 double cacheExtent, /// 子控制元件陣列 List<Widget> children = const <Widget>[], /// 子控制元件的個數 int semanticChildCount, DragStartBehavior dragStartBehavior = DragStartBehavior.start, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, })
builder
Flutter
給我們提供了四種構造ListView
的方法,有ListView()
、ListView.builder()
、ListView.separated()
、ListView.custom()
、
建構函式 | 描述 |
---|---|
ListView() | 靜態構造方法 初始化之前需要確定資料來源的大小 |
ListView.builder() | 動態構造方法 可動態傳入資料 |
ListView.separated() | 動態構造方法 可動態傳入資料 可動態定製分割線的樣式 |
ListView.custom() | 動態構造方法 需要傳入SliverChildDelegate 來做動態生成 |
靜態構造方法和動態構造方法
ListView()
是初始化的時候需要確定資料來源的大小,一旦初始化成功後不能再次動態的插入資料。
ListView.builder()
、ListView.separated()
、ListView.custom()
可以動態的插入資料,且能夠更小的節省記憶體空間。
我們來看以下程式碼:
Flexible( child: ListView( children: List.generate( 10, (index) { print("without builder index = $index"); return Container( height: 60, child: Card( color: Colors.blue, child: Center(child: Text("$index")), ), ); }, ), ), ), Flexible( child: ListView.builder( itemCount: 10, itemExtent: 60, itemBuilder: (BuildContext contenxt, int index) { print("builder index = $index"); return Container( height: 60, child: Card( color: Colors.red, child: Center(child: Text("$index")), ), ); }, ), ),
同樣是需要初始化10個子控制元件,我們分別在List.generate
方法和itemBuilder
方法中做了列印操作
輸出如下:
flutter: without builder index = 0
flutter: without builder index = 1
flutter: without builder index = 2
flutter: without builder index = 3
flutter: without builder index = 4
flutter: without builder index = 5
flutter: without builder index = 6
flutter: without builder index = 7
flutter: without builder index = 8
flutter: without builder index = 9
flutter: builder index = 0
flutter: builder index = 1
flutter: builder index = 2
flutter: builder index = 3
flutter: builder index = 4
flutter: builder index = 5
flutter: builder index = 6
flutter: builder index = 7
由輸出的log可見,builder
方法只初始化了7個子控制元件,ListView()
方法完整的初始化了10個子控制元件。
builder
方法是在需要使用的時候才會初始化,當頁面滾動到第9個子控制元件的時候,這個時候才會初始化第9個子控制元件。
這樣做的優勢是:當我們的列表資料量很大的時候(比如說有成百上千個數據),我們只初始化幾個來滿足頁面的顯示需求,其他的控制元件在需要的時候,再做初始化這樣就大大的幫助我們節省記憶體空間。
scrollDirection
ListView
同時具備了水平佈局和垂直佈局的能力,我們只需要給scrollDirection
設定不同的引數即可。
scrollDirection
接收的引數值有兩個Axis.vertical
和Axis.horizontal
Axis.vertical
效果如下
Axis.horizontal
效果如下
reverse
引數reverse
可以控制列表是按正序顯示還是倒序顯示。
reverse = true
表示倒序顯示
reverse = false
表示正序顯示
physics
某些情況下我們並不想要ListView
可以滾動,只要把physics
設定為NeverScrollableScrollPhysics
即可。
physics
還有其他兩個比較重要的值:
ClampingScrollPhysics
:在Android裝置上有微光效果。
BouncingScrollPhysics
:在iOS裝置上有彈性效果。
separated
在ListView.separated()
建構函式中,我們可以傳入一個自定義的Divider
來作作為分隔的樣式
這裡我們來看一下Divider
都有哪些引數:
const Divider({
/// key
Key key,
// 高度
this.height,
/// 顏色的 高度
this.thickness,
/// 開頭處的縮排
this.indent,
/// 結束處的縮排
this.endIndent,
/// 顏色
this.color,
})
height = 0
height = 10
thinkness = 10
indent = 100
end = 100
想體驗以上示例的執行效果,可以到我的Github倉庫專案flutter_app
->lib
->routes
->listview_page.dart
檢視,並且可以下載下來執行並體驗。