从网络获取数据并展示,是很常规的操作。下面我们一起来看下在Flutter中如何实现这个过程。
先上效果图:
listview.gif
准备工作:
- 使用的是AndroidStudio 开发
- 网络请求使用 dio库,在项目pubspec.yaml 中引入dio库;
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
english_words: ^3.1.0
dio: 3.0.8
json_annotation: ^2.0.0
dev_dependencies:
flutter_test:
sdk: flutter
json_serializable: ^2.0.0
- json转Bean网站 https://javiercbk.github.io/json_to_dart/
正文
首先从网络获取数据,这里使用了鸿洋大神的wanAndroid网站的开发API作为数据源,代码如下:
Future<Map> request(String url) async{
Response response = await new Dio().get(url);
return response.data;
}
void _getDataList(){
Future<Map> map=request("https://www.wanandroid.com/article/list/0/json");
map.then((result){
ArticleListResp tb=ArticleListResp.fromJson(result);
setState(() {
articles=tb.data.datas;
});
});
}
上面代码准备好了数据源,剩下就是向ListView中填充数据。
填充数据代码如下:
ListView.builder(
shrinkWrap:true,
itemCount: articles.length,
itemBuilder: (context,pos){
//填充ListView的Item
return _buildRow(articles[pos]);
}
),
完整代码如下:
Bean类
class ArticleListResp {
ArticleListControler data;
int errorCode;
String errorMsg;
ArticleListResp({this.data, this.errorCode, this.errorMsg});
ArticleListResp.fromJson(Map<String, dynamic> json) {
data = json['data'] != null ? new ArticleListControler.fromJson(json['data']) : null;
errorCode = json['errorCode'];
errorMsg = json['errorMsg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data.toJson();
}
data['errorCode'] = this.errorCode;
data['errorMsg'] = this.errorMsg;
return data;
}
}
class ArticleListControler {
int curPage;
List<Article> datas;
int offset;
bool over;
int pageCount;
int size;
int total;
ArticleListControler(
{this.curPage,
this.datas,
this.offset,
this.over,
this.pageCount,
this.size,
this.total});
ArticleListControler.fromJson(Map<String, dynamic> json) {
curPage = json['curPage'];
if (json['datas'] != null) {
datas = new List<Article>();
json['datas'].forEach((v) {
datas.add(new Article.fromJson(v));
});
}
offset = json['offset'];
over = json['over'];
pageCount = json['pageCount'];
size = json['size'];
total = json['total'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['curPage'] = this.curPage;
if (this.datas != null) {
data['datas'] = this.datas.map((v) => v.toJson()).toList();
}
data['offset'] = this.offset;
data['over'] = this.over;
data['pageCount'] = this.pageCount;
data['size'] = this.size;
data['total'] = this.total;
return data;
}
}
class Article {
String apkLink;
int audit;
String author;
int chapterId;
String chapterName;
bool collect;
int courseId;
String desc;
String envelopePic;
bool fresh;
int id;
String link;
String niceDate;
String niceShareDate;
String origin;
String prefix;
String projectLink;
int publishTime;
int selfVisible;
int shareDate;
String shareUser;
int superChapterId;
String superChapterName;
List<Tag> tags;
String title;
int type;
int userId;
int visible;
int zan;
Article(
{this.apkLink,
this.audit,
this.author,
this.chapterId,
this.chapterName,
this.collect,
this.courseId,
this.desc,
this.envelopePic,
this.fresh,
this.id,
this.link,
this.niceDate,
this.niceShareDate,
this.origin,
this.prefix,
this.projectLink,
this.publishTime,
this.selfVisible,
this.shareDate,
this.shareUser,
this.superChapterId,
this.superChapterName,
this.tags,
this.title,
this.type,
this.userId,
this.visible,
this.zan});
Article.fromJson(Map<String, dynamic> json) {
apkLink = json['apkLink'];
audit = json['audit'];
author = json['author'];
chapterId = json['chapterId'];
chapterName = json['chapterName'];
collect = json['collect'];
courseId = json['courseId'];
desc = json['desc'];
envelopePic = json['envelopePic'];
fresh = json['fresh'];
id = json['id'];
link = json['link'];
niceDate = json['niceDate'];
niceShareDate = json['niceShareDate'];
origin = json['origin'];
prefix = json['prefix'];
projectLink = json['projectLink'];
publishTime = json['publishTime'];
selfVisible = json['selfVisible'];
shareDate = json['shareDate'];
shareUser = json['shareUser'];
superChapterId = json['superChapterId'];
superChapterName = json['superChapterName'];
if (json['tags'] != null) {
tags = new List<Tag>();
json['tags'].forEach((v) {
tags.add(new Tag.fromJson(v));
});
}
title = json['title'];
type = json['type'];
userId = json['userId'];
visible = json['visible'];
zan = json['zan'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['apkLink'] = this.apkLink;
data['audit'] = this.audit;
data['author'] = this.author;
data['chapterId'] = this.chapterId;
data['chapterName'] = this.chapterName;
data['collect'] = this.collect;
data['courseId'] = this.courseId;
data['desc'] = this.desc;
data['envelopePic'] = this.envelopePic;
data['fresh'] = this.fresh;
data['id'] = this.id;
data['link'] = this.link;
data['niceDate'] = this.niceDate;
data['niceShareDate'] = this.niceShareDate;
data['origin'] = this.origin;
data['prefix'] = this.prefix;
data['projectLink'] = this.projectLink;
data['publishTime'] = this.publishTime;
data['selfVisible'] = this.selfVisible;
data['shareDate'] = this.shareDate;
data['shareUser'] = this.shareUser;
data['superChapterId'] = this.superChapterId;
data['superChapterName'] = this.superChapterName;
if (this.tags != null) {
data['tags'] = this.tags.map((v) => v.toJson()).toList();
}
data['title'] = this.title;
data['type'] = this.type;
data['userId'] = this.userId;
data['visible'] = this.visible;
data['zan'] = this.zan;
return data;
}
}
class Tag {
String name;
String url;
Tag({this.name, this.url});
Tag.fromJson(Map<String, dynamic> json) {
name = json['name'];
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['url'] = this.url;
return data;
}
}
视图:
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
primaryColor: Colors.redAccent,
),
home:ListViewShowData(),
);
}
}
class ListViewShowData extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return ListViewShowDataState();
}
}
class ListViewShowDataState extends State<ListViewShowData>{
List<Article> articles;
Future<Map> request(String url) async{
Response response = await new Dio().get(url);
return response.data;
}
void _getDataList(){
Future<Map> map=request("https://www.wanandroid.com/article/list/0/json");
map.then((result){
ArticleListResp tb=ArticleListResp.fromJson(result);
setState(() {
articles=tb.data.datas;
});
});
}
Widget _buildRow(Article bean){
TextStyle style=new TextStyle(fontSize: 13);
return new Container(
margin: new EdgeInsets.all(10),
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Row(
children: <Widget>[
new Offstage(
offstage: !bean.niceDate.contains("小时"),
child: new Container(
margin: new EdgeInsets.fromLTRB(0, 0, 10, 0),
child: new Text("新",style: new TextStyle(color: Colors.blue,fontSize: 13),),
),
),
new Text(bean.author.isEmpty?bean.shareUser:bean.author,maxLines: 1,style: style,),
new Expanded(
child: new Text(bean.niceDate,textAlign: TextAlign.right,style: style,),
),
],
),
new Row(
children: <Widget>[
new Expanded(
child:new Text(bean.title,softWrap: true,style: new TextStyle(fontWeight: FontWeight.bold),),
),
],
),
new Row(
children: <Widget>[
new Offstage(
offstage: bean.type==0,
child:new Container(
margin: new EdgeInsets.fromLTRB(0, 0, 10, 0),
child: new Text("置顶",style: new TextStyle(color: Colors.red,fontSize: 13),),
),
),
new Expanded(
child:new Container(
alignment: Alignment.centerLeft,
child: new Text(bean.superChapterName+"·"+bean.chapterName,style: style,),
),
),
new Icon(Icons.favorite_border,color: Colors.red,),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
if(articles==null){
//如果没有数据源则开始获取数据
_getDataList();
}
return Scaffold(
appBar: AppBar( //相当于Android中的actionbar
title:Text(
"ListView"
),
),
//如果还没数据源,则返回 正在加载 页面
body: articles==null? Container(alignment: Alignment.center,child: Text("正在加载",textAlign: TextAlign.center,),):
ListView.builder(
shrinkWrap:true,
itemCount: articles.length,
itemBuilder: (context,pos){
//填充ListView的Item
return _buildRow(articles[pos]);
}
),
);
}
}
网友评论