Flutter实现网络请求的方法示例

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网络请求并且展示数据就这样实现的。

最后附上demo地址: https://github.com/xinhuashi/flutter_http_demo.git

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

(0)

相关推荐

  • Flutter中网络图片加载和缓存的实现

    前言 应用开发中经常会碰到网络图片的加载,通常我们会对图片进行缓存,以便下次加载同一张图片时不用再重新下载,在包含有大量图片的应用中,会大幅提高图片展现速度.提升用户体验且为用户节省流量.Flutter本身提供的Image Widget已经实现了加载网络图片的功能,且具备内存缓存的机制,接下来一起看一下Image的网络图片加载的实现. 重温小部件Image 常用小部件Image中实现了几种构造函数,已经足够我们日常开发中各种场景下创建Image对象使用了. 有参构造函数: Image(Key k

  • Flutter 网络请求框架封装详解

     Flutter 请求网络的三种方式 flutter 请求网络的方式有三种,分别是 Dart 原生的网络请求 HttpClient.第三方网络请求 http以及 Flutter 中的 Dio.我们可以比较一下这三种网络请求方式,然后封装为我们方便请求网络的工具类. Dart 原生的网络请求 HttpClient 实现 Dart 获取网络数据的请求,一般我们需要以下几个步骤: step 1: 原生的网络请求时不需要修改 pubspec.yaml 文件的,我们只需要在使用的地方引入所需包就可以了 i

  • Flutter网络请求的3种简单实现方法

    概述: App几乎都离不开与服务器的交互,本文主要讲解了flutter网络请求三种方式 flutter自带的HttpClient. 第三方库http 和 第三方库Dio  的简单实现 GET 和 POST请求,本文是笔者学习Flutter网络模块知识总结,若有问题还望不腻赐教. 一.系统自带HttpClient 1.使用中温馨提示 1.1.导入库 import 'dart:io'; // 网络请求 import 'dart:convert'; // 数据解析 1.2.Uri的多种初始化方式 //

  • Flutter实现网络请求的方法示例

    Flutter网络请求使用的是Dio.Dio是一个强大易用的dart http请求库,支持Restful API.FormData.拦截器.请求取消.Cookie管理.文件上传/下载....... Flutter json数据解析是使用了json_serializable package包.它是一个自动化源代码生成器,可以为我们生成JSON序列化模板.由于序列化代码不再由我们手写和维护,我们将运行时产生JSON序列化异常的风险降至最低. Flutter网络请求数据并且展示效果图: 数据接口 数据

  • Flutter Http网络请求实现详解

    Http网络请求是一门开发语言里比较常用和重要的功能,主要用于资源访问.接口数据请求和提交.上传下载文件等等操作,Http请求方式主要有:GET.POST.HEAD.PUT.DELETE.TRACE.CONNECT.OPTIONS.本文主要GET和POST这两种常用请求在Flutter中的用法,其中对POST将进行着重讲解.Flutter的Http网络请求的实现主要分为三种:io.dart里的HttpClient实现.Dart原生http请求库实现.第三方库实现.后面将会给大家详细讲解这几种区别

  • PHP实现网络请求的方法总结

    一.分析php发送网网络请求的方法 对于php发送网络请求,我们最常用的请求就是curl,有时我们也会用到file_get_contents函数发送网络请求,但file_get_contents只能完成一些间单的网络请求,稍复杂的就无法完成,例如文件上传,cookies,验证,表单提交等,用php的curl可以使用URL的语法模拟浏览器来传输数据,因为它是模拟浏览器,因此它同样支持多种协议,FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及

  • node.js通过axios实现网络请求的方法

    1.使用Npm 下载axios npm install --save axios var update_url = axios.create({ baseURL:'debug url' }); update_url.get('/debug url').then(function (response){ //response 就是请求url 返回的内容 } 上述的方法请求文件时候,body的默认格式不是form-data.因此我们需要请求的数据格式为form-data的时候,需要使用下面的库 re

  • 关于React Native使用axios进行网络请求的方法

    在前端开发中,能够完成数据请求的方式有很多,如Ajax.jQuery ajax.axios和fetch等.不过,随着技术的发展,现在能够看到的基本上也就axios和fetch两种. axios是一个基于Promise的Http网络库,可运行在浏览器端和Node.js中,Vue应用的网络请求基本都是使用它完成的.axios有很多优秀的特性,如支持请求的拦截和响应.取消请求.JSON自动转换.客户端防御XSRF等. 使用axios之前,需要先在项目中安装axios插件,安装命令如下. //npm n

  • React网络请求发起方法详细介绍

    目录 1. 发起网络请求 2. 开发时网络请求代理配置 1. 发起网络请求 首先需要安装 axios 库: yarn add axios 发起网络请求: import React, { Component } from 'react' import { get } from './utils/http' import Loading from './components/Loading' class App extends Component { state = { users: null }

  • 详解flutter之网络请求dio,请求,拦截器简单示例

    flutter一直很火的网络请求插件dio 直接上代码,写成一个类,可以直接使用 包含请求的封装,拦截器的封装 import 'package:dio/dio.dart'; import 'dart:async'; import 'dart:io'; import './apidomain.dart'; import './httpHeaders.dart'; import 'package:shared_preferences/shared_preferences.dart'; class D

  • iOS开发中使用NSURLConnection类处理网络请求的方法

    NSURLConnection 作为 Core Foundation / CFNetwork 框架的 API 之上的一个抽象,在 2003 年,随着第一版的 Safari 的发布就发布了.NSURLConnection 这个名字,实际上是指代的 Foundation 框架的 URL 加载系统中一系列有关联的组件:NSURLRequest.NSURLResponse.NSURLProtocol. NSURLCache. NSHTTPCookieStorage.NSURLCredentialStor

  • Kotlin结合Rxjava+Retrofit实现极简网络请求的方法

    前言 因为最近正在写的项目集成了两个网络请求框架(Volley and Retrofit)对比之下也是选择了Retrofit.既然选择那自然要让自己以后开发更加省力(就是懒).于是我在Retrofit中加入了Rxjava,这也是当下蛮流行的一个请求框架.然后又利用了Kotlin的一些新特性,使网络请求变得特别简单,代码量特别少. Kotlin镇楼 RxJava RxJava学习是一个曲折漫长的过程,但一旦掌握,妙用无穷. 通过这里了解更多:http://www.jb51.net/article/

  • PHP使用curl_multi实现并发请求的方法示例

    本文实例讲述了PHP使用curl_multi实现并发请求的方法.分享给大家供大家参考,具体如下: class CurlMultiUtil { /** * 根据url,postData获取curl请求对象,这个比较简单,可以看官方文档 */ private static function getCurlObject($url,$postData=array(),$header=array()){ $options = array(); $url = trim($url); $options[CUR

随机推荐