關(guān)于Flutter列表ListView的那些事兒

flutter里面的listview支持豎直列表和水平列表。

水平列表
 scrollDirection: Axis.horizontal
垂直列表
scrollDirection:  Axis.vertical

listview的創(chuàng)建方式也多種多樣。

item數(shù)量固定的

可以直接采用children賦值,直接添加子item即好。

new ListView(
  children: <Widget>[
    new Container(
      width: 160.0,
      color: Colors.red,
    ),
    new Container(
      width: 160.0,
      color: Colors.blue,
    ),
    new Container(
      width: 160.0,
      color: Colors.green,
    ),
    new Container(
      width: 160.0,
      color: Colors.yellow,
    ),
    new Container(
      width: 160.0,
      color: Colors.orange,
    ),
  ],
)
子item數(shù)量是可變的

用builder方式構(gòu)建。

 new ListView.builder(
      itemCount: items.length,
      itemBuilder: (context, index) {
        return Container(
          child: new Text('${items[index]}'),
        );
      },
    );

如果想給item添加分割線,可以根據(jù)index的奇偶性判斷何時添加。

index.isOdd //判斷是否是奇數(shù)

判斷是否是奇數(shù)。

final index = i ~/ 2;//表示i除以2,但返回值是整形(向下取整),比如i為:1, 2, 3, 4, 5時,
        // 結(jié)果為0, 1, 1, 2, 2

用上面方法可以不用為divider造假數(shù)據(jù)。
另外還有一種專門添加分隔線的listview的生成方法。

ListView.separated(
      itemBuilder: (BuildContext context, int index) {
        if (index == catergoryChildList.length) {
          return buildCircleProgressBar();
        } else {
          CatergoryChild catergoryChild = catergoryChildList[index];
          return ItemView(catergoryChild, index, (index) {
            Scaffold.of(context)
                .showSnackBar(SnackBar(content: Text("第$index項被點擊了")));
          });
        }
      },
      separatorBuilder: (context, index) {
        return new Divider(
          height: 1,
        );
      },
      scrollDirection: Axis.vertical,
      itemCount: catergoryChildList.length + 1,
      controller: scrollController,
    );

這種方法更加方便快捷,也不用造divider數(shù)據(jù),有單獨生成divider的地方。

listview的下拉刷新。
RefreshIndicator(
      child: listViewM,
      onRefresh: () async{
        getData();
      },
      color: Colors.blue,
    );

這樣就實現(xiàn)了android Mateial風格的下拉刷新。
getData()方法如下:

void getData(){
    if (!isFetching) {
      catergoryChildTask.getCatergoryTask(type);
      isFetching = true;
    }
  }

需要注意的是onRefresh字段需要的是一個async的方法,如果不是async的方法會報錯。
也可以這樣寫:

RefreshIndicator(
      child: listViewM,
      onRefresh: getData,
      color: Colors.blue,
    );

但此時getData方法是這樣實現(xiàn)的。

  Future<Null> getData() async{
    if (!isFetching) {
      catergoryChildTask.getCatergoryTask(type);
      isFetching = true;
    }
    return null;
  }
listview的上拉加載更多

listview的上拉加載更多的觸發(fā)是通過ScrollController控制的。
滾動到底部的檢測條件如下:

 scrollController.addListener(() {
      if (scrollController.position.pixels ==
          scrollController.position.maxScrollExtent) {
        loadMore=true;
        getData();
      }
    });

listview最下部顯示正在加載中的進度條的處理可以參考如下

 itemBuilder: (BuildContext context, int index) {
        if (index == catergoryChildList.length) {
          return buildCircleProgressBar();
        } else {
          CatergoryChild catergoryChild = catergoryChildList[index];
          return ItemView(catergoryChild, index, (index) {
            Scaffold.of(context)
                .showSnackBar(SnackBar(content: Text("第$index項被點擊了")));
          });
        }
      }

其中buildCircleProgressBar的方法處理如下:

  Widget buildCircleProgressBar() {
    return Padding(
      padding: EdgeInsets.all(8),
      child: Center(child: Opacity(
          opacity: 1, child: CircularProgressIndicator()),
      ),);
  }

這樣就實現(xiàn)了拉到最底部時顯示正在加載中的子item狀態(tài)。如果想要其他的處理,可以自行處理。
本文完整源代碼地址:
https://github.com/happycodinggirl/flutter_gank
有什么問題,歡迎交流。

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

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