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");
        }
      },
    );
  }
}

效果展示

Flutter的ListVIew获取并动态展示JSON数据_第1张图片

你可能感兴趣的:(Android,flutter)