GridView组件。一个可滚动的二维空间数组。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
在使用无限加载滚动列表的时候,最先使用的还是ListView组件。但若是要一行显示2列或者更多列的滚动列表,GridView组件更为方便。如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
在向服务器请求数据后,服务器往往会返回一段json字符串。而我们要想更加灵活的使用数据的话需要把json字符串转化成对象。由于flutter只提供了json to Map。而手写反序列化在大型项目中极不稳定,很容易导致解析失败。所有最好使用json_serializable 自动反序列化。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
首先在文件中dependencies添加json_annotation,dev_dependencies添加json_serializable文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 json_annotation: ^2.0.0 cached_network_image: ^0.5.1 transparent_image: ^0.1.0 dio: ^1.0.9 video_player: ^0.7.2 flutter_spinkit: ^2.1.0 dev_dependencies: build_runner: ^1.0.0 json_serializable: ^2.0.0 flutter_test: sdk: flutter
以json_serializable的方式创建model类
创建一个模型文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
import 'package:json_annotation/'; part ''; @JsonSerializable() class PicModel { PicModel(this.createdAt,this.publishedAt,this.type,this.url); String createdAt; String publishedAt; String type; String url; factory PicModel.fromJson(Map<String,dynamic> json) => _$PicModelFromJson(json); }
此时这个文件是不存在的,必须运行代码生成器来为我们生成序列化模板。通过在我们的项目根目录下运行flutter packages pub run build_runner build
,我们可以在需要时为我们的model生成json序列化代码。 这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
然后建立文件,搭建基础构架。引入相关的库文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
import 'package:flutter/'; import 'dart:io'; import 'dart:convert'; import 'package:flutter_yuan/models/'; import 'package:cached_network_image/'; class FindPage extends StatefulWidget{ FindPage({Key key}):super(key:key); @override createState() => new _FindPageState(); } class _FindPageState extends State<FindPage> { List<PicModel> picList = new List(); int page = 1; @override void initState() { (); _getPicList(); } @override Widget build(BuildContext context) { returnnew Scaffold( ); } }
我们需要通过_getPicList来异步请求数据:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
_getPicList() async{ String url = '$page'; var httpClient = new HttpClient(); try { var req = await httpClient.getUrl((url)); var res = await req.close(); // print(res);if(res.statusCode == HttpStatus.OK) { var jsonString = await res.transform().join();//将结果转换成字符串拼接// print(jsonString); Map data = jsonDecode(jsonString);//格式化成Map对象 print(data); List pics = data['data']; List<PicModel> items = new List(); for (var value in pics) { (new PicModel.fromJson(value)); }; setState(() { this.picList.addAll(items); this.page ++; }); } } catch (e) { } }
然后构建Widget:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
Widget build(BuildContext context) { returnnew Scaffold( appBar: new AppBar( title: new Text('美图'), centerTitle: true, ), body: new ( padding: const EdgeInsets.all(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: , crossAxisSpacing: , ), itemCount: picList.length, itemBuilder: (BuildContext context, int index) { if(index == picList.length - 1 ){ _getPicList(); } return buildItem(picList[index]); }, ), ); }
使用组件来构建列表,通过gridDelegate属性来对列表样式进行丰富。crossAxisCount属性可以设置每行的列数,打造你的瀑布流布局。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
buidItem方法对图片的样式布局。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/10475.html
buildItem(item) { returnnew GestureDetector( onTap: () { ( context, new MaterialPageRoute( builder: (context) => new Scaffold( appBar: new AppBar( title: new Text('图片详情'), ), body: new Center( child: new Container( width: 300.0, child: new CachedNetworkImage( imageUrl: item.url, fit: BoxFit.fitWidth, ), ) ), ) ) ); }, child: new CachedNetworkImage( errorWidget: new Icon(), imageUrl: item.url, fadeInDuration: new Duration(seconds: 3), fadeOutDuration: new Duration(seconds: 1), ), ); }