【Android实战开发】flutter实现网络请求的方法示例

news2024/12/25 2:25:24

Flutter网络请求使用的是Dio。Dio是一个强大易用的dart http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载…….

Flutter json数据解析是使用了json_serializable package包。它是一个自动化源代码生成器,可以为我们生成JSON序列化模板。由于序列化代码不再由我们手写和维护,我们将运行时产生JSON序列化异常的风险降至最低。

Flutter网络请求数据并且展示效果图:
在这里插入图片描述
数据接口

数据是使用的聚合数据的API,影讯API合集,大家可以注册个账号,申请使用一下,像这样
在这里插入图片描述
添加依赖

在pubspec.yaml文件中添加所需要的第三方依赖库

environment:
 sdk: " =2.1.0 <3.0.0"

 dependencies:
  flutter:
   sdk: flutter
 
  json_annotation: ^2.0.0
  connectivity: ^0.4.2
  dio: ^2.0.15
  event_bus: ^1.0.3
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
 
 dev_dependencies:
  flutter_test:
   sdk: flutter

网络请求过程分析

  static netFetch(url,params,Map<String,String  header,Options option,{noTip = false}) async {
   //获取网络的连接状态,如果没有连接网络,返回NETWORK_ERROR
   var connectivityResult = await (new Connectivity().checkConnectivity());
   if(connectivityResult == ConnectivityResult.none) {
    return new ResultData(Code.errorHandleFunction(Code.NETWORK_ERROR, "", noTip),false,Code.NETWORK_ERROR);
   }
   //请求头存放集合
   Map<String,String  headers = new HashMap();
   if(header != null) {
    headers.addAll(header);
   }
   //option存放请求的一些配置信息
   if(option != null) {
    option.headers = headers;
   }else {
    //get请求
    option = new Options(method:'get');
    option.headers = headers;
   }
   //超时时间15000ms
   option.connectTimeout = 15000;
   //创建dio对象
   Dio dio = new Dio();
   Response response;
   try{
    //执行网络请求,await和async配合使用,表示这是一个异步耗时操作
    //执行结果不会立马返回。
    response = await dio.request(url,data: params,options: option);
   }on DioError catch(e) {
    //异常处理
    ....
    return new ResultData(Code.errorHandleFunction(errorResponse.statusCode, e.message, noTip), false, errorResponse.statusCode);
   }
   try{
     if(response.statusCode == 200 || response.statusCode == 201) {
      //网络请求成功
      return await new ResultData(response.data, true, Code.SUCCESS,headers: response.headers);
     }
   }catch(e) {
    //异常处理
    print('返回参数' + e.toString() + url);
    return new ResultData(response.data, false, response.statusCode,headers: response.headers);
   }
   return new ResultData(Code.errorHandleFunction(response.statusCode, "", noTip), false, response.statusCode);
  }

这个是最底层类封装了一个静态的请求方法,直接调用dio的request方法进行网路请求,很简单。

  //如果这个是耗时方法,就会用async标记,耗时操作用await标记,表示是一个异步操作。
  static getTodayFilmListDao() async {
   //获取请求的url
   String url = Address.getTodayFilmList();
   //调用上面封装的网络请求方法进行网络请求
   var res = await HttpManager.netFetch(url, null, null, null);
   if(res != null && res.result) {
    var data = res.data;
    if(data == null || data.length == 0) {
     return await new DataResult([],true);
    }
    //网络请求成功,进行数据解析
    var response = TodayFilmResponse.fromJson(data);
    //返回数据
    return await new DataResult(response.result,true);
   }else {
    return await new DataResult(null,false);
   }
  }

获取url方法很简单,就是字符串拼接了一下

static getTodayFilmList() {
   return "${host}movie/movies.today?cityid=1&dtype=&key=713a408e855352d913806ef1e3ce3c33";
  }

下面分析一下json数据解析过程。

如上所说,json解析使用的是json_serializable package包。它是一个自动化源代码生成器,可以为我们生成JSON序列化模板。

网络请求获取到的json数据是这样的

{
        "movieId":"135808",
        "movieName":"新喜剧之王",
        "pic_url":"http:\/\/img5.mtime.cn\/mt\/2019\/02\/02\/113216.53857992_182X243X4.jpg"
      },
  
TodayFilmBean类

    //TodayFilmBean.g.dart将在我们运行生成命令之后自动生成
    part 'TodayFilmBean.g.dart';
    
    //这个标注是告诉生成器,这个类是要生成的Model类
    @JsonSerializable()
    class TodayFilmBean{
     String movieId;
     String movieName;
     String pic_url;
     
      //构造函数
     TodayFilmBean(this.movieId,this.movieName,this.pic_url);
     
     //json转换为bean对象
     factory TodayFilmBean.fromJson(Map<String,dynamic  json) =  _$todayFilmBeanFromJson(json);
     
     //bean对象转换为json
     Map<String,dynamic  toJson() =  _$todayFilmBeanToJson(this);
    }
生成的TodayFilmBean.g.dart类是这样的

    part of 'TodayFilmBean.dart';
    
    //json转换为bean对象
    TodayFilmBean _$todayFilmBeanFromJson(Map<String,dynamic  json) {
     return TodayFilmBean(json['movieId'] as String,json['movieName'] as String,
       json['pic_url'] as String);
    }
    
    //bean对象转换为json
    Map<String,dynamic  _$todayFilmBeanToJson(TodayFilmBean instance) = 
      <String,dynamic  {
       'movieId': instance.movieId,
       'movieName': instance.movieName,
       'pic_url':instance.pic_url
    };

有两种运行代码生成器的方法:

1.一次性生成

通过在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的model生成json序列化代码。这触发了一次性构建,它通过我们的源文件,挑选相关的并为它们生成必要的序列化代码。

虽然这非常方便,但如果我们不需要每次在model类中进行更改时都要手动运行构建命令的话会更好。

2.持续生成

使用_watcher_可以使我们的源代码生成的过程更加方便。它会监视我们项目中文件的变化,并且在需要时自动构建必要的文件。我们可以通过flutter packages pub run build_runner watch 在项目根目录下运行来启动_watcher_。

只需启动一次观察器,然后并让它在后台运行,这是安全的。

执行序列化只需执行

//把json数据转化为了bean对象
var filmBean = TodayFilmBean.fromJson(json);

使用GridView最终展示结果

 DataResult dataResult;
  List<TodayFilmBean  mData = [];
  
  //当StatefulWiget被嵌入此view树中,就会为此widget创建State对象
  //当State对象被创建了,frameWork就会调用initState()方法
  @override
  void initState() {
   //初始化数据
   getTodayFilm();
   super.initState();
  }
  
  
  void getTodayFilm() async {
   //这是一个异步操作,结果返回有一定延迟
   dataResult = await TodayDao.getTodayFilmListDao();
   //调用setState方法会通知framework控件状态有变化,它会立马触发
   //State的build方法更新widget状态
   setState(() {
    mData = dataResult.data;
   });
  }

上面是初始化网络请求,在请求到数据后,调用setState刷新UI

  //State的build方法,调用setState方法后,此方法就会被触发
   //用来刷新UI
   @override
   Widget build(BuildContext context) {
  
    return Scaffold(
     appBar: AppBar(
  
      title: Text(widget.title),
     ),
     
     //如果mData.length == 0,展示一个loading框,否则展示数据
     body: mData.length == 0
       ? new Center(child: new CircularProgressIndicator()):
       //创建GridView对象
       new GridView.builder(
  
       gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
         crossAxisCount: 3, //每行2个
         mainAxisSpacing: 1.0, //主轴(竖直)方向间距
         crossAxisSpacing: 1.0, //纵轴(水平)方向间距
         childAspectRatio: 0.7 //纵轴缩放比例
       ),
       //item数量
       itemCount:mData.length,

       //创建每个item
       itemBuilder: (BuildContext context,int index) {
        return _getWidget(index);
       }),
    );
   }

 _getWidget(int index) {
  //添加要展示的item内容
   return new Column(
    children: <Widget [
     new Expanded(child: new CardItem(color: Colors.black12,child: _getChild(index)),flex: 8,),
     //显示网络请求文本
     new Expanded(child: new Text(mData[index].movieName,
      textAlign: TextAlign.end,
      maxLines: 1,
     ),
       flex:1)
    ]);
 }

 _getChild(int i) {
  return new Padding(padding: new EdgeInsets.all(1.0),
    //显示网络请求的图片
    child: new Image(image: NetworkImage(mData[i].pic_url)));
 }

一个自定义的CardItem

class CardItem extends StatelessWidget{
 final Widget child;
 final EdgeInsets margin;
 final Color color;
 final RoundedRectangleBorder shape;
 final double elevation;

 CardItem({@required this.color,this.child,this.elevation = 5.0,this.shape,this.margin});

 @override
 Widget build(BuildContext context) {
  EdgeInsets margin = this.margin;
  RoundedRectangleBorder shape = this.shape;
  Color color = this.color;
  margin ??= EdgeInsets.only(left: 2.0,top: 2.0,right: 2.0,bottom: 2.0);
  shape ??= new RoundedRectangleBorder(borderRadius: new BorderRadius.all(Radius.circular(4.0)));
  color ??= new Color(0xffeeff);
  return new Card(elevation: elevation,shape: shape,color: color,margin: margin,child: child,);
 }
}

好了,Flutter网络请求并且展示数据就这样实现的。

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/431452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++快速幂详解例题

基本概念 什么是快速幂呢&#xff1f;个人理解&#xff0c;就是更快速的计算幂运算。 比如计算a^b 刚学这个算法的时候我也很疑惑&#xff0c;幂运算不是有现成的公式么&#xff0c;直接pow&#xff08;a,b&#xff09;不就好了吗&#xff1f; 后来才明白&#xff0c;pow(a,b)的…

三分钟了解什么是时序数据库

在介绍时序数据库之前&#xff0c;我们先来看看什么是时序数据。时序数据就是基于时间排序的数据&#xff0c;再通过时间坐标将这些数据连接起来&#xff0c;形成一个折线图&#xff0c;直观地展示一个指标在过去一段时间内的走势和规律&#xff0c;帮助定位数据异常点。 时序…

Oracle中Archived redolog的生成

目录 一、问题预览 二、问题解答 一、问题预览 大家都知道 Oracle 中 online redolog切换后会生成 archived redolog&#xff0c;心里默认的就是 online redolog 切换后 archived redolog 已经生成。切换示意图&#xff0c;如下图所示。 但事实真的是这样吗&#xff1f; 二、…

C++ 23 实用工具(一)

C 23 实用工具&#xff08;一&#xff09; 工具函数是非常有价值的工具。它们不仅可以用于特定的领域&#xff0c;还可以应用于任意值和函数&#xff0c;甚至可以创建新的函数并将它们绑定到变量上。 常用函数 你可以使用各种变体的 min、max 和 minmax 函数来对值和初始化列…

【使用ChatGPT自动化】批量转换.xls文件为.xlsx文件

第1次提问&#xff1a; 我&#xff1a;我想使用Python批量转换.xls文件为.xlsx文件&#xff0c;请你提供代码 它&#xff1a; 当涉及到批量处理文件时&#xff0c;我们通常需要使用Python中的os模块和glob模块。os模块用于管理文件和目录&#xff0c;glob模块用于匹配文件路径名…

Visual Studio Code 1.77 发布!

欢迎使用 Visual Studio Code 2023 年3月版。此版本有许多更新&#xff0c;其中一些主要亮点包括&#xff1a; 无障碍改进&#xff1a;新的悬停、通知和 Sticky Scroll 快捷键 复制 GitHub 深度链接&#xff1a;在编辑器内创建永久链接和 HEAD 链接 笔记本保存格式&#xff1…

软件测试流程进阶----四年软件测试总结

工作四年了&#xff0c;我一直希望让自己每年对测试的理解更深入一层。工作一年的时候&#xff0c;我谈轮了自己对各种测试的理解&#xff0c;这一年来&#xff0c;虽然对那些理概念的有所加强&#xff0c;自我感觉没有什么质的变化。前些天听我们公司的一位测试经理讲《敏捷测…

精准抓住核心要点!!!十名面试官总结出这样一份面试通关答案,还不赶紧开始“作弊”通关!!!

金三银四求职季&#xff0c;但最近很多朋友私信说&#xff1a; 熬过了去年的寒冬&#xff0c;却没躲过如今的内卷&#xff1b; 打开Boss直拒&#xff0c;一排已读不回&#xff1b; 大部分回复的都是外包&#xff0c;薪资低于预期&#xff0c;对技术水平要求却远超从前&#x…

大数据和 CRM系统:它们如何帮助中小企业?

作为中小企业主&#xff0c;你可能在想&#xff0c;"大数据与我有什么关系&#xff1f;"但如果你使用某些类型的业务应用&#xff0c;即使预算很少&#xff0c;你也可以从大数据中获益。一个最好的例子是客户关系管理&#xff08;CRM&#xff09;系统&#xff0c;它提…

二极管反向恢复过程详细解析

二极管反向恢复过程&#xff0c;现代脉冲电路中大量使用晶体管或二极管作为开关, 或者使用主要是由它们构成的逻辑集成电路。而作为开关应用的二极管主要是利用了它的通(电阻很小)、断(电阻很大) 特性, 即二极管对正向及反向电流表现出的开关作用。二极管和一般开关的不同在于,…

在线帮助中心对企业的作用及解决方案

帮助中心对于一款互联网产品来说&#xff0c;重要性不言而喻。随着公司客户服务水平的不断提高&#xff0c;越来越多的公司逐渐重视客户服务。一个好的在线帮助中心必定能提高客户的转化率。那么&#xff0c;在线帮助中心对企业的帮助和作用有哪些呢? 在线帮助中心的作用 1.快…

3.10——常类型

常类型的引入&#xff0c;就是为了既保证数据共享又防止数据被改动。常类型是指使用类型修饰符const说明的类型&#xff0c;常类型的变量或对象成员的值在程序运行期间是不可改动的。 常引用 如果在说明引用时用const修饰&#xff0c;则被说明的引用为常引用。如果用常引用作为…

adb环境变量配置

adb环境变量配置Android一. 简介二. 环境变量配置1.JDK安装2.SDK安装3. 资源共享4. 配置环境变量4.1 方式一&#xff1a;4.2 方式二&#xff1a;5. adb常用命令的使用6. 结果Android List of ADB Commands and Fastboot Commands for Android 如果你是一个android用户&#xf…

paddleocr,windows pip 安装巨坑 lanms 库

安装 lanms 最佳参考&#xff1a; paddleocr&#xff0c;windows pip 安装巨坑 lanms 库 防丢失&#xff0c;直接抄录的一份 paddleocr最后几个库一个比一个难装&#xff0c;特别是 lanms 库&#xff0c;巨难装&#xff0c;拒绝任何花里胡哨&#xff0c;十分钟&#xff0c;三步…

HTML5 <menu> 标签

HTML5 <menu> 标签 实例 HTML5 <menu>标签用于定义菜单列表。 两个菜单按钮系列选项实例&#xff08;"File" 和 "Edit"&#xff09;&#xff1a; <menu type"toolbar"> <li> <menu label"File"> &…

Linux-初学者系列——篇幅4_系统运行相关命令

系统运行相关命令-目录一、关机重启注销命令1、重启或者关机命令-shutdown语法格式&#xff1a;常用参数&#xff1a;01 指定多久关闭/重启系统02 指定时间关闭/重启系统03 实现立即关闭/重启系统04 取消关闭/重启系统计划2、重启或者关机命令-halt/poweroff/reboot/systemctl语…

Lucene Solr Elasticsearch三者之间的关系,怎么选?

Lucene简介&#xff1a; Lucene主要用于构建文本搜索应用程序&#xff0c;包括Web搜索引擎、桌面搜索工具和商业应用程序。它提供了诸如单词分析、查询解析、搜索结果排序等功能&#xff0c;可以轻松地在大量文档中快速搜索和查找相关信息。 Lucene具有以下特点&#xff1a; …

Linux -- 进阶 Web 服务器 基础前瞻 ( 一 )

目录 WWW 简介 &#xff1a; 组件一个网站得需要哪些东西呢 &#xff1f;&#xff1f; 1 得有 响应用户申请网页服务 的软件 2 服务器主机 3 那就需要数据了 4. 浏览器 预备知识 &#xff1a; 网址及HTTP 简介 &#xff1a; URL : http 请求方法 &#xff1a;…

关于使用云渲染的五大优势

在不影响质量或性能的情况下节省时间、金钱和资源&#xff0c;对于需要在通常较短且严格的期限内创建高质量 3D 内容的专业人士来说&#xff0c;云渲染都是最好的选择&#xff01;云渲染作为数字媒体生产的最新趋势&#xff0c;与传统的渲染农场和机器相比具有许多优势&#xf…

每个程序员都应该知道的 5 个基本 Matlab 提示和技巧

当今软件开发和数据分析领域中&#xff0c;Matlab 是一种十分常用的工具。然而&#xff0c;对于许多程序员而言&#xff0c;它的高级特性可能并不为人所知。在本文中&#xff0c;我们将分享每个程序员都应该知道的 5 个基本 Matlab 提示和技巧&#xff0c;以帮助你更好地使用这…