Flutter的ListVIew获取并动态展示JSON数据
插件配置
dio: ^4.0.4
信息获取——netConfig类
import 'dart:io';import 'package:dio/dio.dart';class NetConfig{ static String baseurl="http://localhost:8888/articleList/pageview_article";//接口地址,与后台交互 static getArticle() async {//异步处理try{ // ignore: unused_local_variable var response =await Dio().post(baseurl);//发送post请求,获取接口返回的数据 if(response.statusCode==200){//判断是否请求成功 return response; }}catch(e){ //捕获异常 // ignore: avoid_print print(e.toString());}return null; }}
NetConfig这个类中,可以定义很多与后台交互的方法,这里为了展示我只定义了一个方法getArticle(),为了方便我将方法定义为了静态方法,同时为了避免不必要的错误,使用了异步处理await前缀(注意在使用此前缀时,方法上必须加上async异步字样),然后就是调用了Dio的网络通信来获取数据
方法使用——ListViewDemo类
import 'dart:convert';import 'package:flutter/material.dart';import 'package:patient_project/utils/NetConfig.dart';import 'package:patient_project/utils/articleUsertoken.dart';class ListViewDemo extends StatefulWidget { const ListViewDemo({ Key key }) : super(key: key); @override State createState() => _ListViewDemoState();}class _ListViewDemoState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Demo'), ), body: FutureBuilder(//处理异步数据 future: NetConfig.getArticle(),//调用NetConfig的getArticle方法 builder: (context,snapshot){ if(snapshot.hasData){//判断是否有数据 var _data=jsonDecode(snapshot.data.toString()); //这里返回的时json格式数据,所以要对数据进行解码,jsonDecode是convert中的一个类用来对json解码 var article=articleToken.fromJson(_data); //解码后的数据转实体类 return ListView.builder(itemCount: article.data.length,//数据的长度itemBuilder: (context,index){ return Container( child: Text(article.data[index].articleTitle), );}, ); }else{ Text("no data"); } }, ), ); }}
为了大家方便理解我使用了有状态管理(当然大家也可以用getX来编写更方便哦),FutureBuilder是flutter处理异步数据常用的方法,future属性可以调用一个异步方法,builder属性里面可以进行数据处理,比如判断数据是否为空,因为这里返回的时json格式数据,所以要对数据进行解码,jsonDecode是convert中的一个类用来对json解码,同时为了方便后面操作,我将解码后的json转成了实体类,可以搜一下JSON to Dart Converter - Convert JSON Code Online,具体使用如下
好原理完美已经讲完了,下面开始正式操作
实体类articleToken
class articleToken { bool success; int code; String msg; List data; articleToken({this.success, this.code, this.msg, this.data}); articleToken.fromJson(Map json) { success = json['success']; code = json['code']; msg = json['msg']; if (json['data'] != null) { data = []; json['data'].forEach((v) { data.add(new Data.fromJson(v)); }); } } Map toJson() { final Map data = new Map(); data['success'] = this.success; data['code'] = this.code; data['msg'] = this.msg; if (this.data != null) { data['data'] = this.data.map((v) => v.toJson()).toList(); } return data; }}class Data { int id; String emailuser; String username; String articleTitle; String isattention; String isComment; String content; int agree; int disagree; int comment; int sharecount; String imageurl; String articletime; int viewCounts; // String? articleTime; // String? articleTitle; // String? imageUrl; Data( {this.id, this.emailuser, this.username, this.articleTitle, this.isattention, this.isComment, this.content, this.agree, this.disagree, this.comment, this.sharecount, this.imageurl, this.articletime, this.viewCounts, // this.articleTime, // this.articleTitle, // this.imageUrl }); Data.fromJson(Map json) { id = json['id']; emailuser = json['emailuser']; username = json['username']; articleTitle = json['articletitle']; isattention = json['isattention']; isComment = json['is_comment']; content = json['content']; agree = json['agree']; disagree = json['disagree']; comment = json['comment']; sharecount = json['sharecount']; imageurl = json['imageurl']; articletime = json['articletime']; viewCounts = json['view_counts']; // articleTime = json['article_time']; // articleTitle = json['article_title']; // imageUrl = json['image_url']; } Map toJson() { final Map data = new Map(); data['id'] = this.id; data['emailuser'] = this.emailuser; data['username'] = this.username; data['articletitle'] = this.articleTitle; data['isattention'] = this.isattention; data['is_comment'] = this.isComment; data['content'] = this.content; data['agree'] = this.agree; data['disagree'] = this.disagree; data['comment'] = this.comment; data['sharecount'] = this.sharecount; data['imageurl'] = this.imageurl; data['articletime'] = this.articletime; data['view_counts'] = this.viewCounts; // data['article_time'] = this.articleTime; // data['article_title'] = this.articleTitle; // data['image_url'] = this.imageUrl; return data; }}
主界面
import 'dart:convert';import 'package:dio/dio.dart';import 'package:flutter/cupertino.dart';import 'package:flutter/material.dart';import 'package:date_format/date_format.dart';import 'package:get/get.dart';import 'package:patient_project/Home/details/details_Conditions/chat.dart';import 'package:patient_project/utils/Color.dart';import 'package:patient_project/utils/articleUsertoken.dart';class ArticleShow extends StatefulWidget { @override State createState() => _ArticleListState();}class _ArticleListState extends State { Color color = Colors.red.shade900; // ignore: prefer_typing_uninitialized_variables static Map json; String guanzhu = "关注"; DateTime dateTime = DateTime.now(); Icon icon = Icon(Icons.add); Widget Rowdate( BuildContext context, double scale, Data data, String anniutitle) { return Row( // crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( child: new Text('${data.username}',style: TextStyle(fontSize: 20 * scale, fontWeight: FontWeight.w700)), ), SizedBox( width: 100 * scale, ), new Text( data.articletime, // formatDate(DateTime.now(), // [yyyy, "-", mm, "-", dd, " ", HH, ":", nn, ":", ss]), style: Theme.of(context).textTheme.subtitle2, ), SizedBox( width: 400 * scale, ), RaisedButton( color: Colors.red, textColor: Colors.red, child: Row( children: [Icon(Icons.add, color: Colors.white),SizedBox( width: 15 * scale,),Text( "关注", style: TextStyle( color: Colors.white, fontSize: 10 * scale, ),), ], ), shape: RoundedRectangleBorder(side: BorderSide( color: Colors.white, width: 1 * scale,),borderRadius: BorderRadius.circular(8 * scale)), // onPressed: () { // setState(() { // if (acticle.isattention=="false") { //color = Colors.grey.shade600; //guanzhu = "已关注"; //icon = Icon(Icons.add_task); //acticle.isattention = "true"; // } else { //Color color = Colors.red.shade900; //String guanzhu = "关注"; // } // }); // // Navigator.of(context).pushNamed('/Sign'); // }, ), ], ); } @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; double scale = size.width / 1920; double sizeWidth = MediaQuery.of(context).size.width; double sizeHeight = MediaQuery.of(context).size.height; return SingleChildScrollView( child: ArticleShowList(scale, sizeWidth, sizeHeight, context), ); } Future getArticle() async { try { String articleUrl = "http://localhost:8888/articleList/pageview_article"; Dio dio = new Dio(); print("开始请求数据"); var response = await dio.post(articleUrl); if (response.statusCode == 200) { return response; } print("请求完成"); } catch (e) { print(e.toString()); } return null; } // List getlist() { // getArticle().then((result) { // json = jsonDecode(result.toString()); // }).whenComplete(() { // print("异步任务处理完成"); // print(json['data']); // articleToken content = articleToken.fromJson(json); // print(content.data[1].emailuser); // return content.data; // }).catchError(() { // print("出现异常了"); // }); // } ArticleShowList( double scale, double sizeWidth, double sizeHeight, BuildContext context) { // List list = getlist(); return FutureBuilder( future: getArticle(), builder: (context, snapshot) { if (snapshot.hasData) { var _data = jsonDecode(snapshot.data.toString()); var _content = articleToken.fromJson(_data); return Row( mainAxisAlignment: MainAxisAlignment.center, children: [Container( padding: EdgeInsets.all(10), // height: sizeHeight, width: 1200 * scale, // alignment: Alignment.center, // decoration: BoxDecoration(color: Colors.amber), child: Container( height: sizeHeight, child: ListView.builder( itemCount: 5, itemBuilder: (context, index) { print(_content.data[index].articleTitle); return Card( elevation: 10, child: GestureDetector( onTap: () {Get.to(ChatView(), arguments: {'data': _content.data[index]}, transition:Transition.zoom, ); }, child: ListTile(title: Text( _content.data[index].articleTitle, // articleContent.articlrTitle, style: TextStyle( fontWeight: FontWeight.bold, ),),subtitle: Container( child: Column( children: [ SizedBox( height: 10, ), Row( children: [ Container( height: 40 * scale, width: 40 * scale, margin: const EdgeInsets.only(right: 16.0), child: CircleAvatar(backgroundImage: NetworkImage( _content.data[index].imageurl), ), ), // SizedBox(height: 10,), Rowdate(context, scale,_content.data[index], guanzhu) ], ), SizedBox( height: 10, ), Container( padding: EdgeInsets.only(bottom: 10), child: Text( _content.data[index].content, overflow: TextOverflow.fade, maxLines: 2, )), Row( children: [ RaisedButton( color: Colors.blue[100], textColor: Colors.white, child: Row(children: [ Icon(Icons.sentiment_satisfied, color: Colors.blue), SizedBox( width: 15 * scale, ), Text( "${'${_content.data[index].agree}'}同意", style: TextStyle( color: Colors.black, fontSize: 10 * scale, ), ),], ), onPressed: () {}, ), SizedBox( width: 10 * scale, ), RaisedButton( color: Colors.blue[100], textColor: Colors.white, child: Row(children: [ Icon(Icons.sentiment_dissatisfied, color: Colors.blue), SizedBox( width: 15 * scale, ), Text( '${_content.data[index].disagree}反对', style: TextStyle( color: Colors.black, fontSize: 10 * scale, ), ),], ), onPressed: () {setState(() { '$index';});// Navigator.of(context).pushNamed('/Sign'); }, ), SizedBox( width: 150 * scale, ), FlatButton( color: Colors.white, textColor: Colors.white, child: Row(children: [ Icon(Icons.comment, color: Colors.blue), SizedBox( width: 15 * scale, ), Text( "${'${_content.data[index].comment}'}条评论", style: TextStyle( color: Colors.black, fontSize: 10 * scale, ), ),], ), onPressed: () {setState(() { '$index';}); }, ), SizedBox( width: 10 * scale, ), FlatButton( color: Colors.white, textColor: Colors.white, child: Row(children: [ Icon(Icons.share, color: Colors.blue), SizedBox( width: 15 * scale, ), Text( "${_content.data[index].sharecount}次分享", style: TextStyle( color: Colors.black, fontSize: 10 * scale, ), ),], ), onPressed: () {setState(() { index++;});// Navigator.of(context).pushNamed('/Sign'); }, ), SizedBox( width: 10 * scale, ), Text( "${_content.data[index].agree}次收藏", ), SizedBox( width: 10 * scale, ), FlatButton( color: Colors.white, textColor: Colors.white, child: Row(children: [ Icon( Icons.visibility, color: Colors.yellow, ), SizedBox( width: 15 * scale, ), Text( "${_content.data[index].viewCounts}浏览", style: TextStyle( color: Colors.black, fontSize: 10 * scale, ), ),], ), onPressed: () {setState(() { index++;});// Navigator.of(context).pushNamed('/Sign'); }, ) ], ) ], ),), ), ), ); }, ), ),), ], ); } else { Text("no data"); } }, ); }}
效果展示
创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖