Flutter使用ListView載入列表資料
阿新 • • 發佈:2018-11-01
移動端UI展示最常見的展示形式莫過於列表,Android中使用ListView/Recyclerview,iOS也有UIListView,都可以實現列表展示。Flutter作為相容Android和iOS的移動UI框架,自然也有實現此功能的元件,即ListView。
本文資料採用爬蟲爬取華爾街見聞全球資訊,然後採用GraphQL介面請求資料。顯示效果如下
實現
- 建立ListView 及每個顯示的item
- 網路請求
- json解析
- 資料顯示
建立ListView及每個顯示的item
使用如下程式碼建立一個ListView
其中listData 為列表載入的資料,因先初始化下 List listData = [];
ListView getListView() => new ListView.builder(
itemCount: (listData== null) ? 0 : listData.length,
itemBuilder: (BuildContext context, int position) {
return getItem(position);
});
上面的getItem方法即為列表item的佈局,使用Column與Row實現垂直和水平佈局,核心程式碼如下:
new Padding( padding: new EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), child: new Column( children: <Widget>[ new Row( crossAxisAlignment: CrossAxisAlignment.start, //縱向對齊方式:起始邊對齊 mainAxisSize: MainAxisSize.max, children: <Widget>[ new Expanded( child: Container( height: 95.0, child: getImage(data.articleThumbnail),//封面 alignment: FractionalOffset.center, ), flex: 1, ), new Expanded( child: Container( height: 95.0, margin: new EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0), child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ new Container( child: new Text( articleTitle,//標題 style: new TextStyle( fontSize: 20.0, fontWeight: FontWeight.w700), maxLines: 1, overflow: TextOverflow.ellipsis, ), alignment: FractionalOffset.topLeft, ), new Container( child: new Text("${data.articleBrief}",//概要 style: new TextStyle(fontSize: 16.0), maxLines: 2, overflow: TextOverflow.ellipsis), alignment: Alignment.topLeft, ), new Expanded( child: new Container( margin: new EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 0.0), child: new Stack( children: <Widget>[ new Container( child: new Text("${data.articleAuthor}", style: new TextStyle(fontSize: 10.0)),//作者 alignment: FractionalOffset.bottomLeft, ), new Container( child: new Text(time_str, style: new TextStyle(fontSize: 10.0)),//時間 alignment: FractionalOffset.bottomRight, ), ], ), ), ) ], ), ), flex: 3, ), ], ), new Divider(), //分割線 ], ), ) /** * 列表中圖片載入 */ getImage(String img_url) { return new CachedNetworkImage( imageUrl: img_url, errorWidget: new Icon(Icons.error), fit: BoxFit.cover, height: 85.0, width: 100.0, ); }
上述程式碼對應顯示效果如下:
程式碼中CachedNetworkImage為網路圖片快取元件cached_network_image載入。
網路請求
網路請求使用的是開源的Dio,也可以直接使用http傳送請求,
Dio dio = new Dio();
Response response = await dio.get(url);
var jsonString = response.data;
json解析
json_serializable這個可以對json做很好的解析,類似於安卓的Gson,具體使用可以參考這篇文章,博主也是按文章進行操作的。
try {
var news = new news_enity.fromJson(jsonString);
var code = news.code;
if (code == 0) {
Result result = news.result;
datas = result.data;
}
} catch (e) {
print("異常==》" + e.toString());
}
資料顯示
使用 setState,將請求獲得的資料datas傳遞給ListView的資料來源listData
setState(() {
listData= datas;
});
但列表顯示肯定是要等到下網路請求到時間後才能顯示的,所以有段時間我們需要用精度條轉圈來顯示等待,沒有資料時,載入loading進度條,有資料後立馬顯示列表
getBody() {
if (listData.isEmpty) {
return getProgressDialog();
} else {
return new Container(
padding: new EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
child: getListView(),
);
}
}
getProgressDialog() {
// // CircularProgressIndicator是一個圓形的Loading進度條
return new Center(child: new CircularProgressIndicator());
}
最後效果如下圖
專案原始碼地址,此專案為持續開發專案,歡迎Start和Fork