这里踩了一脚坑,写flutter的时候还是与js有差异的,这里主要涉及到几个知识点,看官需要对几部分内容先理解才容易处理,PS:其实现在我也还有点懵~

1. 网络请求,这里我分别使用了dio和http两个库

2. dart的json解析,不得不说,这个真神奇~

3 listView渲染及嵌套listView

4 FutureBuilder使用

吐槽:

坑1: dart对json的处理其实真的不方便,不能像js那样拿来就用,起初也找了一些json转换的插件,但是用着也都很不爽,一直有各种错误抛出来,最后决定还是自己写model解析json;

坑2: listView的嵌套主要注意一下子listView需要多设置两个属性就可以了,应该是为了解决滑动和计算子项高度的。

坑3:异步渲染还是使用FutureBuilder吧,这东西简单好用,最初我像js那样建一个全局变量,然后在http请求之后,使用setstate去赋值,看着逻辑很对,但是一直在第一次渲染的时候报空指针,我猜是还没有返回数据就渲染ui了,但是一直没解决掉,也可能是那个时候json解析还不太对,后来使用了这个FutureBuilder,从此没有烦恼了~

特别深奥的原理我还解释不清,只记录一下踩坑的点,大家多注意即可

下面是代码,欢迎指正,我分别给出我的dio请求库,和此处功能实现的代码

1 dio请求库

import 'package:dio/dio.dart';
import 'dart:async';class DioUtil{/// global dio objectstatic Dio dio;/// default optionsstatic const String API_PREFIX = 'http://10.0.3.2:8086/ylr-admin';static const int CONNECT_TIMEOUT = 10000;static const int RECEIVE_TIMEOUT = 3000;/// http request methodsstatic const String GET = 'get';static const String POST = 'post';static const String PUT = 'put';static const String PATCH = 'patch';static const String DELETE = 'delete';/// request methodstatic Future<Map> request(String url, {data, method}) async{data = data ?? {};method = method ?? GET;/// restful 请求处理/// /gysw/search/hist/:user_id        user_id=27/// 最终生成 url 为     /gysw/search/hist/27data.forEach((key, value){if(url.indexOf(key) != -1){url = url.replaceAll(':$key', value.toString());}});/// 打印请求相关信息:请求地址、请求方式、请求参数
//    print('请求地址:【' + method + '  ' + url + '】');
//    print('请求参数:' + data.toString());Dio dio = createInstance();var result;try {Response response = await dio.request(url, data: data, options: new Options(method: method));result = response.data;/// 打印响应相关信息
//      print('响应数据:' + response.toString());} on DioError catch (e) {/// 打印请求失败相关信息
//      print('请求出错:' + e.toString());}return result;}/// 创建 dio 实例对象static Dio createInstance () {if (dio == null) {/// 全局属性:请求前缀、连接超时时间、响应超时时间BaseOptions options = BaseOptions(baseUrl: API_PREFIX,connectTimeout: CONNECT_TIMEOUT,receiveTimeout: RECEIVE_TIMEOUT,);dio = new Dio(options);}return dio;}/// 清空 dio 对象static clear () {dio = null;}}

我也是参考其他人的写法,拿来用的,这里说明一下API_PREFIX ,我用的genymotion模拟器 ,这个东西和本地交互的ip是10.0.3.2

2 功能实现

import 'dart:convert';import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:ylr_app/base/base_detail.dart';
import 'package:ylr_app/constants/constants.dart';
import 'package:ylr_app/utils/dio_util.dart';
import 'package:ylr_app/widget/home_news_more.dart';
import 'package:http/http.dart' as http;/// 资讯
class HomeNews extends StatefulWidget {@override_HomeNewsState createState() => _HomeNewsState();
}class _HomeNewsState extends State<HomeNews> {// httpFuture<NewsModel> fetchPost() async {final response =await http.get(Constants.BASE_URL + '/api/article/getArticleList');Utf8Decoder utf8decoder = Utf8Decoder(); //fix 中文乱码var result = json.decode(utf8decoder.convert(response.bodyBytes));return NewsModel.fromJson(result);}// dioFuture<NewsModel> _getDataList() async {var result = await DioUtil.request('/api/article/getArticleList',method: DioUtil.GET);return NewsModel.fromJson(result);}Widget _listItemBuilder(item) {return GestureDetector(child: Container(margin: EdgeInsets.only(top: 10,),height: ScreenUtil().setHeight(60),child: Flex(direction: Axis.horizontal,mainAxisAlignment: MainAxisAlignment.spaceAround,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[Expanded(flex: 1,child: Text('${item.title}',overflow: TextOverflow.ellipsis,),),Container(alignment: Alignment.centerRight,width: ScreenUtil().setWidth(260),child: item.updateTime != null ?Text(formatDate(DateTime.parse('${item.updateTime}'), [yyyy, '-', mm, '-', dd],)):Text(formatDate(DateTime.parse('${item.createTime}'), [yyyy, '-', mm, '-', dd],)),),],),),onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => BaseDetail(contentTitle: '${item.title}',isShowVideo: false,id: int.parse('${item.id}'),),),);},);}Widget _createListView(BuildContext context, AsyncSnapshot snapshot){if(snapshot.hasData){//数据处理var data = snapshot.data;List<NewsItemModel> listData = (data.result as List).cast();return ListView.builder(shrinkWrap: true,physics: NeverScrollableScrollPhysics(),itemBuilder: (context, index) {NewsItemModel item = listData[index];return _listItemBuilder(item);},itemCount: listData.length,);}}Widget _buildFuture(BuildContext context, AsyncSnapshot snapshot) {switch (snapshot.connectionState) {case ConnectionState.none:return Text('还没开始网络请求');case ConnectionState.active:return Text('ConnectionState.active');case ConnectionState.waiting:return Center(child: CircularProgressIndicator(),);case ConnectionState.done:if (snapshot.hasError) return Text('Error: ${snapshot.error}');return _createListView(context, snapshot);default:return null;}}@overrideWidget build(BuildContext context) {return Container(margin: EdgeInsets.only(bottom: 5),decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),border: Border.all(color: Color(Constants.border),),),child: Padding(padding: EdgeInsets.all(10),child: Column(children: <Widget>[Container(decoration: BoxDecoration(image: DecorationImage(image: AssetImage('assets/images/listbar.png'),fit: BoxFit.fitWidth,),),child: Row(children: <Widget>[Container(width: ScreenUtil().setWidth(360),margin: EdgeInsets.only(left: 10),child: Text(Constants.MODULE_HOME_NEWS,style: TextStyle(fontSize: Constants.font40,),),),Expanded(flex: 1,child: GestureDetector(child: Row(mainAxisAlignment: MainAxisAlignment.end,children: <Widget>[Text(Constants.MORE,style: TextStyle(fontSize: Constants.font30,),),Icon(Icons.arrow_forward_ios,color: Colors.grey,size: Constants.font36,),],),onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => HomeNewsMore(),),);},),),],),),FutureBuilder(builder: _buildFuture,future: _getDataList(),),],),),);}
}// dart model
class NewsModel {int code;int timestamp;String message;bool success;List<NewsItemModel> result;NewsModel({this.code, this.timestamp, this.message, this.success, this.result});factory NewsModel.fromJson(Map<String, dynamic> json) {final originList = json['result'] as List;List<NewsItemModel> newsItemModelList =originList.map((value) => NewsItemModel.fromJson(value)).toList();return NewsModel(code: json['code'],timestamp: json['timestamp'],message: json['message'],success: json['success'],result: newsItemModelList);}
}class NewsItemModel {int id;String title;String createTime;String updateTime;NewsItemModel({this.id, this.title, this.createTime, this.updateTime});factory NewsItemModel.fromJson(Map<String, dynamic> json) {return NewsItemModel(id: json['id'],title: json['title'],createTime: json['createTime'],updateTime: json['updateTime']);}
}

这里给出了两种http请求库的使用方法,以及它们分别如何与自定义的dart model转换,最终生成列表是使用listView做的,原本的想法,是用for循环数据List渲染UI,也是一直报各种问题,最终都使用flutter提供的组件实现了,我想应该是会有其他办法实现,但是我对dart的语法还是不够熟悉,现阶段只能这么做了,以后有机会再试试其他写法,有知道的朋友路过,欢迎指教,提供给我一下事例代码,我就瞟一眼~

Flutter 异步加载数据并渲染列表相关推荐

  1. 在Vue中异步加载数据渲染到Dom

    在Vue中异步加载数据渲染到Dom 问题 <div v-for="o in resmessage" :key="o" class="text i ...

  2. 新手教程:不写JS,在MIP页中实现异步加载数据

    从需求谈起:在 MIP 页中异步加载数据 MIP(移动网页加速器) 的 加速原理 除了靠谱的 MIP-Cache CDN 加速外,最值得一提的就是组件系统.所有 JS 交互都需要使用 MIP 组件实现 ...

  3. 可视化 | Echarts基础异步加载数据交互组件数据集

    目录 1. ECharts 简介 2. ECharts 安装 3. ECharts 配置语法 4. ECharts 图饼 5. ECharts 样式设置 6. ECharts 异步加载数据 7. EC ...

  4. 淘宝购物车页面 智能搜索框Ajax异步加载数据

    如果有朋友对本篇文章的一些知识点不了解的话,可以先阅读此篇文章.在这篇文章中,我大概介绍了一下构建淘宝购物车页面需要的基础知识. 这篇文章主要探讨的是智能搜索框Ajax异步加载数据.jQuery的社区 ...

  5. ajax实现向上正在加载,向上滚动或者向下滚动分页异步加载数据(Ajax + lazyload)

    /**** desc : 分页异步获取列表数据,页面向上滚动时候加载前面页码,向下滚动时加载后面页码 ajaxdata_url ajax异步的URL 如data.php page_val_name a ...

  6. Flutter异步加载FutureBuilder重绘解决方案

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 通过FutureBui ...

  7. element ui table组件 异步加载数据盒子位移

    使用element ui 中的 table组件时 ,异步加载数据,然后渲染上去时会出现td与th对不齐,但是重新重新进一次就有又好了,但是对于用户体验肯定是不行的. 这个时候只需要使用element ...

  8. python 异步加载_Python学习笔记4——爬取异步加载数据

    一.什么是异步加载? 在之前的学习笔记中,爬取的网页是需要手动翻页的网址,但是一些网站是通过自动加载翻页的,如knewone网页.浏览knewone的官网就能发现,当下拉到网页最下端时,网站会自动加载 ...

  9. 学习下ECharts 异步加载数据

    ECharts 通常数据设置在 setOption 中,如果我们需要异步加载数据,可以配合 jQuery等工具,在异步获取数据后通过 setOption 填入数据和配置项就行. ECharts 通常数 ...

最新文章

  1. 东莞市商业学校计算机平面设计在哪个校区,东莞市商业学校
  2. 转:SQL Server 2005安装过程图解
  3. 【Java】优雅停机时的一点思考
  4. 串口程序设计——struct termios结构体
  5. 生意场上,这些社交暗语不可不懂
  6. roundcube webmail登陆失败怎么回事_智慧团建登陆官网入口手机
  7. python海龟隐藏_Python海龟绘图——常用方法指令
  8. **********模拟新浪微博*********
  9. C# CSharp计算标准偏差 重复精度 和Excel中的STDEV函数相同
  10. 野火FPGA征途Pro学习笔记(IP核)
  11. 一款非常棒的开源微社区轻论坛类源码
  12. PHP字体间距设置,wps字间距怎么调整
  13. 推荐 :大数据下的用户与价值分析
  14. 分子动力学(二)-成键相互作用
  15. BIM技术在住宅园区物业管理中的应用及其优势
  16. 开源的 IM 项目 Sealtalk
  17. 1116: [POI2008]CLO
  18. 2021年危险化学品经营单位主要负责人考试及危险化学品经营单位主要负责人考试题
  19. iOS 添加自定义文字字体样式
  20. Catia 开始界面

热门文章

  1. 前端下载文件方法、 后台接口返回二进制文件流、前端通过blob对象并使用fetch/axios实现下载
  2. a8处理器相当于骁龙几_手机处理器的各项参数都是什么意思?手把手教你
  3. 垃圾回收器(CMS)
  4. 自媒体人的福音,比今日热榜还实用的热点工具来了——全网热点直达
  5. 当前的人工智能还是弱人工智能 目前还在积极探索中
  6. HDU4562-守护雅典娜
  7. 腾讯后台开发技术总监浅谈过载保护 小心雪崩效应
  8. cf端游界面更新显示服务器繁忙,【CF】UI界面更新了,那玩家期待已久的经典服务器呢?...
  9. 2022年度APP推荐合集| 颜值高且实用的5款手机必备软件
  10. css 广告、公告。滚动文字从右到左(店铺招牌的动画),不使用marquee标签