• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Flutter的ListVIew获取并动态展示JSON数据

武飞扬头像
今朝.122
帮助1

插件配置

dio: ^4.0.4

信息获取——netConfig类

  1.  
    import 'dart:io';
  2.  
     
  3.  
    import 'package:dio/dio.dart';
  4.  
     
  5.  
     
  6.  
    class NetConfig{
  7.  
    static String baseurl="http://localhost:8888/articleList/pageview_article";
  8.  
    //接口地址,与后台交互
  9.  
     
  10.  
    static getArticle() async {//异步处理
  11.  
    try{
  12.  
    // ignore: unused_local_variable
  13.  
    var response =await Dio().post(baseurl);//发送post请求,获取接口返回的数据
  14.  
    if(response.statusCode==200){//判断是否请求成功
  15.  
    return response;
  16.  
    }
  17.  
    }catch(e){ //捕获异常
  18.  
    // ignore: avoid_print
  19.  
    print(e.toString());
  20.  
    }
  21.  
    return null;
  22.  
    }
  23.  
    }
学新通

NetConfig这个类中,可以定义很多与后台交互的方法,这里为了展示我只定义了一个方法getArticle(),为了方便我将方法定义为了静态方法,同时为了避免不必要的错误,使用了异步处理await前缀(注意在使用此前缀时,方法上必须加上async异步字样),然后就是调用了Dio的网络通信来获取数据

方法使用——ListViewDemo类

  1.  
    import 'dart:convert';
  2.  
     
  3.  
    import 'package:flutter/material.dart';
  4.  
    import 'package:patient_project/utils/NetConfig.dart';
  5.  
    import 'package:patient_project/utils/articleUsertoken.dart';
  6.  
     
  7.  
    class ListViewDemo extends StatefulWidget {
  8.  
    const ListViewDemo({ Key key }) : super(key: key);
  9.  
     
  10.  
    @override
  11.  
    State<ListViewDemo> createState() => _ListViewDemoState();
  12.  
    }
  13.  
     
  14.  
    class _ListViewDemoState extends State<ListViewDemo> {
  15.  
    @override
  16.  
    Widget build(BuildContext context) {
  17.  
    return Scaffold(
  18.  
    appBar: AppBar(
  19.  
    title: Text('Demo'),
  20.  
    ),
  21.  
    body: FutureBuilder(//处理异步数据
  22.  
    future: NetConfig.getArticle(),//调用NetConfig的getArticle方法
  23.  
    builder: (context,snapshot){
  24.  
    if(snapshot.hasData){//判断是否有数据
  25.  
    var _data=jsonDecode(snapshot.data.toString());
  26.  
    //这里返回的时json格式数据,所以要对数据进行解码,jsonDecode是convert中的一个类用来对json解码
  27.  
    var article=articleToken.fromJson(_data);
  28.  
    //解码后的数据转实体类
  29.  
    return ListView.builder(
  30.  
    itemCount: article.data.length,//数据的长度
  31.  
    itemBuilder: (context,index){
  32.  
    return Container(
  33.  
    child: Text(article.data[index].articleTitle),
  34.  
    );
  35.  
    },
  36.  
    );
  37.  
    }else{
  38.  
    Text("no data");
  39.  
    }
  40.  
    },
  41.  
    ),
  42.  
    );
  43.  
    }
  44.  
    }
学新通

为了大家方便理解我使用了有状态管理(当然大家也可以用getX来编写更方便哦),FutureBuilder是flutter处理异步数据常用的方法,future属性可以调用一个异步方法,builder属性里面可以进行数据处理,比如判断数据是否为空,因为这里返回的时json格式数据,所以要对数据进行解码,jsonDecode是convert中的一个类用来对json解码,同时为了方便后面操作,我将解码后的json转成了实体类,可以搜一下JSON to Dart Converter - Convert JSON Code Online,具体使用如下

学新通

 好的原理我们已经讲完了,下面开始正式操作

实体类articleToken

  1.  
    class articleToken {
  2.  
    bool success;
  3.  
    int code;
  4.  
    String msg;
  5.  
    List<Data> data;
  6.  
     
  7.  
    articleToken({this.success, this.code, this.msg, this.data});
  8.  
     
  9.  
    articleToken.fromJson(Map<String, dynamic> json) {
  10.  
    success = json['success'];
  11.  
    code = json['code'];
  12.  
    msg = json['msg'];
  13.  
    if (json['data'] != null) {
  14.  
    data = <Data>[];
  15.  
    json['data'].forEach((v) {
  16.  
    data.add(new Data.fromJson(v));
  17.  
    });
  18.  
    }
  19.  
    }
  20.  
     
  21.  
    Map<String, dynamic> toJson() {
  22.  
    final Map<String, dynamic> data = new Map<String, dynamic>();
  23.  
    data['success'] = this.success;
  24.  
    data['code'] = this.code;
  25.  
    data['msg'] = this.msg;
  26.  
    if (this.data != null) {
  27.  
    data['data'] = this.data.map((v) => v.toJson()).toList();
  28.  
    }
  29.  
    return data;
  30.  
    }
  31.  
    }
  32.  
     
  33.  
    class Data {
  34.  
    int id;
  35.  
    String emailuser;
  36.  
    String username;
  37.  
    String articleTitle;
  38.  
    String isattention;
  39.  
    String isComment;
  40.  
    String content;
  41.  
    int agree;
  42.  
    int disagree;
  43.  
    int comment;
  44.  
    int sharecount;
  45.  
    String imageurl;
  46.  
    String articletime;
  47.  
    int viewCounts;
  48.  
    // String? articleTime;
  49.  
    // String? articleTitle;
  50.  
    // String? imageUrl;
  51.  
     
  52.  
    Data(
  53.  
    {this.id,
  54.  
    this.emailuser,
  55.  
    this.username,
  56.  
    this.articleTitle,
  57.  
    this.isattention,
  58.  
    this.isComment,
  59.  
    this.content,
  60.  
    this.agree,
  61.  
    this.disagree,
  62.  
    this.comment,
  63.  
    this.sharecount,
  64.  
    this.imageurl,
  65.  
    this.articletime,
  66.  
    this.viewCounts,
  67.  
    // this.articleTime,
  68.  
    // this.articleTitle,
  69.  
    // this.imageUrl
  70.  
    });
  71.  
     
  72.  
    Data.fromJson(Map<String, dynamic> json) {
  73.  
    id = json['id'];
  74.  
    emailuser = json['emailuser'];
  75.  
    username = json['username'];
  76.  
    articleTitle = json['articletitle'];
  77.  
    isattention = json['isattention'];
  78.  
    isComment = json['is_comment'];
  79.  
    content = json['content'];
  80.  
    agree = json['agree'];
  81.  
    disagree = json['disagree'];
  82.  
    comment = json['comment'];
  83.  
    sharecount = json['sharecount'];
  84.  
    imageurl = json['imageurl'];
  85.  
    articletime = json['articletime'];
  86.  
    viewCounts = json['view_counts'];
  87.  
    // articleTime = json['article_time'];
  88.  
    // articleTitle = json['article_title'];
  89.  
    // imageUrl = json['image_url'];
  90.  
    }
  91.  
     
  92.  
    Map<String, dynamic> toJson() {
  93.  
    final Map<String, dynamic> data = new Map<String, dynamic>();
  94.  
    data['id'] = this.id;
  95.  
    data['emailuser'] = this.emailuser;
  96.  
    data['username'] = this.username;
  97.  
    data['articletitle'] = this.articleTitle;
  98.  
    data['isattention'] = this.isattention;
  99.  
    data['is_comment'] = this.isComment;
  100.  
    data['content'] = this.content;
  101.  
    data['agree'] = this.agree;
  102.  
    data['disagree'] = this.disagree;
  103.  
    data['comment'] = this.comment;
  104.  
    data['sharecount'] = this.sharecount;
  105.  
    data['imageurl'] = this.imageurl;
  106.  
    data['articletime'] = this.articletime;
  107.  
    data['view_counts'] = this.viewCounts;
  108.  
    // data['article_time'] = this.articleTime;
  109.  
    // data['article_title'] = this.articleTitle;
  110.  
    // data['image_url'] = this.imageUrl;
  111.  
    return data;
  112.  
    }
  113.  
    }
学新通

主界面

  1.  
    import 'dart:convert';
  2.  
    import 'package:dio/dio.dart';
  3.  
    import 'package:flutter/cupertino.dart';
  4.  
    import 'package:flutter/material.dart';
  5.  
    import 'package:date_format/date_format.dart';
  6.  
    import 'package:get/get.dart';
  7.  
    import 'package:patient_project/Home/details/details_Conditions/chat.dart';
  8.  
    import 'package:patient_project/utils/Color.dart';
  9.  
    import 'package:patient_project/utils/articleUsertoken.dart';
  10.  
     
  11.  
    class ArticleShow extends StatefulWidget {
  12.  
    @override
  13.  
    State<ArticleShow> createState() => _ArticleListState();
  14.  
    }
  15.  
     
  16.  
    class _ArticleListState extends State<ArticleShow> {
  17.  
    Color color = Colors.red.shade900;
  18.  
    // ignore: prefer_typing_uninitialized_variables
  19.  
    static Map<String, dynamic> json;
  20.  
    String guanzhu = "关注";
  21.  
    DateTime dateTime = DateTime.now();
  22.  
    Icon icon = Icon(Icons.add);
  23.  
    Widget Rowdate(
  24.  
    BuildContext context, double scale, Data data, String anniutitle) {
  25.  
    return Row(
  26.  
    // crossAxisAlignment: CrossAxisAlignment.stretch,
  27.  
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
  28.  
    children: <Widget>[
  29.  
    Container(
  30.  
    child: new Text('${data.username}',
  31.  
    style:
  32.  
    TextStyle(fontSize: 20 * scale, fontWeight: FontWeight.w700)),
  33.  
    ),
  34.  
    SizedBox(
  35.  
    width: 100 * scale,
  36.  
    ),
  37.  
    new Text(
  38.  
    data.articletime,
  39.  
    // formatDate(DateTime.now(),
  40.  
    // [yyyy, "-", mm, "-", dd, " ", HH, ":", nn, ":", ss]),
  41.  
    style: Theme.of(context).textTheme.subtitle2,
  42.  
    ),
  43.  
    SizedBox(
  44.  
    width: 400 * scale,
  45.  
    ),
  46.  
    RaisedButton(
  47.  
    color: Colors.red,
  48.  
    textColor: Colors.red,
  49.  
    child: Row(
  50.  
    children: <Widget>[
  51.  
    Icon(Icons.add, color: Colors.white),
  52.  
    SizedBox(
  53.  
    width: 15 * scale,
  54.  
    ),
  55.  
    Text(
  56.  
    "关注",
  57.  
    style: TextStyle(
  58.  
    color: Colors.white,
  59.  
    fontSize: 10 * scale,
  60.  
    ),
  61.  
    ),
  62.  
    ],
  63.  
    ),
  64.  
    shape: RoundedRectangleBorder(
  65.  
    side: BorderSide(
  66.  
    color: Colors.white,
  67.  
    width: 1 * scale,
  68.  
    ),
  69.  
    borderRadius: BorderRadius.circular(8 * scale)),
  70.  
    // onPressed: () {
  71.  
    // setState(() {
  72.  
    // if (acticle.isattention=="false") {
  73.  
    // color = Colors.grey.shade600;
  74.  
    // guanzhu = "已关注";
  75.  
    // icon = Icon(Icons.add_task);
  76.  
    // acticle.isattention = "true";
  77.  
    // } else {
  78.  
    // Color color = Colors.red.shade900;
  79.  
    // String guanzhu = "关注";
  80.  
    // }
  81.  
    // });
  82.  
    // // Navigator.of(context).pushNamed('/Sign');
  83.  
    // },
  84.  
    ),
  85.  
    ],
  86.  
    );
  87.  
    }
  88.  
     
  89.  
    @override
  90.  
    Widget build(BuildContext context) {
  91.  
    Size size = MediaQuery.of(context).size;
  92.  
    double scale = size.width / 1920;
  93.  
    double sizeWidth = MediaQuery.of(context).size.width;
  94.  
    double sizeHeight = MediaQuery.of(context).size.height;
  95.  
    return SingleChildScrollView(
  96.  
    child: ArticleShowList(scale, sizeWidth, sizeHeight, context),
  97.  
    );
  98.  
    }
  99.  
     
  100.  
    Future getArticle() async {
  101.  
    try {
  102.  
    String articleUrl = "http://localhost:8888/articleList/pageview_article";
  103.  
    Dio dio = new Dio();
  104.  
    print("开始请求数据");
  105.  
    var response = await dio.post(articleUrl);
  106.  
    if (response.statusCode == 200) {
  107.  
    return response;
  108.  
    }
  109.  
    print("请求完成");
  110.  
    } catch (e) {
  111.  
    print(e.toString());
  112.  
    }
  113.  
    return null;
  114.  
    }
  115.  
     
  116.  
    // List<Data> getlist() {
  117.  
    // getArticle().then((result) {
  118.  
    // json = jsonDecode(result.toString());
  119.  
    // }).whenComplete(() {
  120.  
    // print("异步任务处理完成");
  121.  
    // print(json['data']);
  122.  
    // articleToken content = articleToken.fromJson(json);
  123.  
    // print(content.data[1].emailuser);
  124.  
    // return content.data;
  125.  
    // }).catchError(() {
  126.  
    // print("出现异常了");
  127.  
    // });
  128.  
    // }
  129.  
     
  130.  
    ArticleShowList(
  131.  
    double scale, double sizeWidth, double sizeHeight, BuildContext context) {
  132.  
    // List<Data> list = getlist();
  133.  
    return FutureBuilder(
  134.  
    future: getArticle(),
  135.  
    builder: (context, snapshot) {
  136.  
    if (snapshot.hasData) {
  137.  
    var _data = jsonDecode(snapshot.data.toString());
  138.  
    var _content = articleToken.fromJson(_data);
  139.  
    return Row(
  140.  
    mainAxisAlignment: MainAxisAlignment.center,
  141.  
    children: [
  142.  
    Container(
  143.  
    padding: EdgeInsets.all(10),
  144.  
    // height: sizeHeight,
  145.  
    width: 1200 * scale,
  146.  
    // alignment: Alignment.center,
  147.  
    // decoration: BoxDecoration(color: Colors.amber),
  148.  
    child: Container(
  149.  
    height: sizeHeight,
  150.  
    child: ListView.builder(
  151.  
    itemCount: 5,
  152.  
    itemBuilder: (context, index) {
  153.  
    print(_content.data[index].articleTitle);
  154.  
    return Card(
  155.  
    elevation: 10,
  156.  
    child: GestureDetector(
  157.  
    onTap: () {
  158.  
    Get.to(ChatView(),
  159.  
    arguments: {'data': _content.data[index]},
  160.  
    transition:Transition.zoom,
  161.  
    );
  162.  
    },
  163.  
    child: ListTile(
  164.  
    title: Text(
  165.  
    _content.data[index].articleTitle,
  166.  
    // articleContent.articlrTitle,
  167.  
    style: TextStyle(
  168.  
    fontWeight: FontWeight.bold,
  169.  
    ),
  170.  
    ),
  171.  
    subtitle: Container(
  172.  
    child: Column(
  173.  
    children: <Widget>[
  174.  
    SizedBox(
  175.  
    height: 10,
  176.  
    ),
  177.  
    Row(
  178.  
    children: <Widget>[
  179.  
    Container(
  180.  
    height: 40 * scale,
  181.  
    width: 40 * scale,
  182.  
    margin:
  183.  
    const EdgeInsets.only(right: 16.0),
  184.  
    child: CircleAvatar(
  185.  
    backgroundImage: NetworkImage(
  186.  
    _content.data[index].imageurl),
  187.  
    ),
  188.  
    ),
  189.  
    // SizedBox(height: 10,),
  190.  
    Rowdate(context, scale,
  191.  
    _content.data[index], guanzhu)
  192.  
    ],
  193.  
    ),
  194.  
    SizedBox(
  195.  
    height: 10,
  196.  
    ),
  197.  
    Container(
  198.  
    padding: EdgeInsets.only(bottom: 10),
  199.  
    child: Text(
  200.  
    _content.data[index].content,
  201.  
    overflow: TextOverflow.fade,
  202.  
    maxLines: 2,
  203.  
    )),
  204.  
    Row(
  205.  
    children: <Widget>[
  206.  
    RaisedButton(
  207.  
    color: Colors.blue[100],
  208.  
    textColor: Colors.white,
  209.  
    child: Row(
  210.  
    children: <Widget>[
  211.  
    Icon(Icons.sentiment_satisfied,
  212.  
    color: Colors.blue),
  213.  
    SizedBox(
  214.  
    width: 15 * scale,
  215.  
    ),
  216.  
    Text(
  217.  
    "${'${_content.data[index].agree}'}同意",
  218.  
    style: TextStyle(
  219.  
    color: Colors.black,
  220.  
    fontSize: 10 * scale,
  221.  
    ),
  222.  
    ),
  223.  
    ],
  224.  
    ),
  225.  
    onPressed: () {},
  226.  
    ),
  227.  
    SizedBox(
  228.  
    width: 10 * scale,
  229.  
    ),
  230.  
    RaisedButton(
  231.  
    color: Colors.blue[100],
  232.  
    textColor: Colors.white,
  233.  
    child: Row(
  234.  
    children: <Widget>[
  235.  
    Icon(Icons.sentiment_dissatisfied,
  236.  
    color: Colors.blue),
  237.  
    SizedBox(
  238.  
    width: 15 * scale,
  239.  
    ),
  240.  
    Text(
  241.  
    '${_content.data[index].disagree}反对',
  242.  
    style: TextStyle(
  243.  
    color: Colors.black,
  244.  
    fontSize: 10 * scale,
  245.  
    ),
  246.  
    ),
  247.  
    ],
  248.  
    ),
  249.  
    onPressed: () {
  250.  
    setState(() {
  251.  
    '$index';
  252.  
    });
  253.  
    // Navigator.of(context).pushNamed('/Sign');
  254.  
    },
  255.  
    ),
  256.  
    SizedBox(
  257.  
    width: 150 * scale,
  258.  
    ),
  259.  
    FlatButton(
  260.  
    color: Colors.white,
  261.  
    textColor: Colors.white,
  262.  
    child: Row(
  263.  
    children: <Widget>[
  264.  
    Icon(Icons.comment,
  265.  
    color: Colors.blue),
  266.  
    SizedBox(
  267.  
    width: 15 * scale,
  268.  
    ),
  269.  
    Text(
  270.  
    "${'${_content.data[index].comment}'}条评论",
  271.  
    style: TextStyle(
  272.  
    color: Colors.black,
  273.  
    fontSize: 10 * scale,
  274.  
    ),
  275.  
    ),
  276.  
    ],
  277.  
    ),
  278.  
    onPressed: () {
  279.  
    setState(() {
  280.  
    '$index';
  281.  
    });
  282.  
    },
  283.  
    ),
  284.  
    SizedBox(
  285.  
    width: 10 * scale,
  286.  
    ),
  287.  
    FlatButton(
  288.  
    color: Colors.white,
  289.  
    textColor: Colors.white,
  290.  
    child: Row(
  291.  
    children: <Widget>[
  292.  
    Icon(Icons.share,
  293.  
    color: Colors.blue),
  294.  
    SizedBox(
  295.  
    width: 15 * scale,
  296.  
    ),
  297.  
    Text(
  298.  
    "${_content.data[index].sharecount}次分享",
  299.  
    style: TextStyle(
  300.  
    color: Colors.black,
  301.  
    fontSize: 10 * scale,
  302.  
    ),
  303.  
    ),
  304.  
    ],
  305.  
    ),
  306.  
    onPressed: () {
  307.  
    setState(() {
  308.  
    index ;
  309.  
    });
  310.  
    // Navigator.of(context).pushNamed('/Sign');
  311.  
    },
  312.  
    ),
  313.  
    SizedBox(
  314.  
    width: 10 * scale,
  315.  
    ),
  316.  
    Text(
  317.  
    "${_content.data[index].agree}次收藏",
  318.  
    ),
  319.  
    SizedBox(
  320.  
    width: 10 * scale,
  321.  
    ),
  322.  
    FlatButton(
  323.  
    color: Colors.white,
  324.  
    textColor: Colors.white,
  325.  
    child: Row(
  326.  
    children: <Widget>[
  327.  
    Icon(
  328.  
    Icons.visibility,
  329.  
    color: Colors.yellow,
  330.  
    ),
  331.  
    SizedBox(
  332.  
    width: 15 * scale,
  333.  
    ),
  334.  
    Text(
  335.  
    "${_content.data[index].viewCounts}浏览",
  336.  
    style: TextStyle(
  337.  
    color: Colors.black,
  338.  
    fontSize: 10 * scale,
  339.  
    ),
  340.  
    ),
  341.  
    ],
  342.  
    ),
  343.  
    onPressed: () {
  344.  
    setState(() {
  345.  
    index ;
  346.  
    });
  347.  
    // Navigator.of(context).pushNamed('/Sign');
  348.  
    },
  349.  
    )
  350.  
    ],
  351.  
    )
  352.  
    ],
  353.  
    ),
  354.  
    ),
  355.  
    ),
  356.  
    ),
  357.  
    );
  358.  
    },
  359.  
    ),
  360.  
    ),
  361.  
    ),
  362.  
     
  363.  
    ],
  364.  
    );
  365.  
    } else {
  366.  
    Text("no data");
  367.  
    }
  368.  
    },
  369.  
    );
  370.  
    }
  371.  
    }
学新通

效果展示

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcafjk
系列文章
更多 icon
同类精品
更多 icon
继续加载