03Flutter--网络请求

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03Flutter--网络请求相关的知识,希望对你有一定的参考价值。

Flutter网络请求

包资源

Flutter包类似于Java语言里的jar包,由全球众多开发者共同提供第三方库。

包仓库

所有包(package)都会发布到Dart的包仓库里,在下面网址输入你想使用的包后点击搜索即可。

包仓库地址为:http://pub.dartlangt.org

使用包需要打开pubspec.yaml文件,在dependencies下添加包的名称及版本:

点击Packages get命令来获取工程配置文件中所添加的引用包,或打开命令行窗口执行flutter packages get命令。

打开main.dart文件,导入url_lancher.dart包

import \'package:flutter/material.dart\';
import \'package:url_launcher/url_launcher.dart\';

此时,就可以使用launch方法来打开url地址:

import \'package:flutter/material.dart\';
import \'package:url_launcher/url_launcher.dart\';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: \'使用第三方包示例\',
      home: Scaffold(
        appBar: AppBar(
          title: Text(\'使用第三方包示例\'),
        ),
        body: Center(
          child: new RaisedButton(
            onPressed: (){
              // 指定url并发起请求
              const url = \'https://www.baidu.com\';
              launch(url);
            },
          ),
        ),
      ),
    );
  }
}

Http请求

Htt[协议通常用于做前后端的数据交互。Flutter请求网络有两种方法,一种是用Http请求,另一种是用HttpClient请求。

  • Http请求方式

在使用Http方式请求网络时,需要导入http包,如下所示:

导入库:http: ^0.12.0+1
导入包:import \'package:http/http.dart\' as http;

下面的示例中发起一个http的get请求,并将返回的结果信息打印到控制台:

import \'package:flutter/material.dart\';
import \'package:http/http.dart\' as http;
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: \'http请求示例\',
      home: new Scaffold(
        appBar: AppBar(
          title: Text(\'http请求示例\'),
        ),
        body: Center(
          child: RaisedButton(
            onPressed: () {
              var url = \'http://httpbin.org/\';
              // 向url发送get请求
              http.get(url).then((response) {
                print("状态: ${response.statusCode}");
                print("正文: ${response.body}");
              });
            },
            child: Text(\'发送http请求\'),
          ),
        ),
      ),
    );
  }
}

HttpClient请求方式

在使用HttpClient方式请求网络时,需要导入io及convert包,如下所示:

import \'dart:convert\';
import \'dart.io\';

请看下面完整示例代码,示例中使用HttpClient请求了一条天气数据,并将返回的结果信息打印到控制台里。

import \'package:flutter/material.dart\';
import \'dart:convert\';
import \'dart:io\';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  // 获取天气数据
  void getWeatherData() async {
    try {
      // 实例化HttpClient对象
      HttpClient httpClient = new HttpClient();
      // 发起请求
      HttpClientRequest request = await httpClient.getUrl(
          Uri.parse("http://wthrcdn.etouch.cn/weather_mini?citykey=101070101"));
      // 等待服务器返回数据
      HttpClientResponse response = await request.close();
      // 使用utf8.decoder从response里解析数据
      var result = await response.transform(utf8.decoder).join();
      // 输出响应头
      print(result);
      httpClient.close();
    } catch (e) {
      print("请求失败: $e");
    } finally {
      // 最后处理操作
    }
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: \'httpClient请求\',
      home: Scaffold(
        appBar: AppBar(title: Text(\'httpClient请求\'),),
        body: Center(
          child: RaisedButton(
            child: Text(\'获取天气数据\'),
            onPressed: getWeatherData,
          ),
        ),
      ),
    );
  }
}

Dio请求方式

Dio是一个强大的Dart Http请求库,支持Restful API、Form-Data、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等。

dio: 3.0.0 #latest version

接下来编写一个获取商品列表数据的示例,具体结构如下所示:

main.dart // 主程序
model // 数据库模型
    good_list_model.dart // 商品列表模型
pages // 视图层
    good_list_page.dart // 商品列表页面
service // 服务层    
    http_service.dart // http请求服务
  1. 在main.dart中的body中添加商品列表页面组件GoodListPage。
import \'package:flutter/material.dart\';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: \'Dio请求\',
      home: Scaffold(
        appBar: AppBar(title: Text(\'Dio请求\'),),
        body: GoodListPage(),
      ),
    );
  }
}

2) 打开http_service.dart,添加request方法。

import \'dart:io\';
import \'package:dio/dio.dart\';
// Dio请求封装
Future request(url, {formData}) async {
  try{
    Response response;
    Dio dio = new Dio();
    dio.options.contentType = ContentType.parse(\'application/x-www-form-urlencoded\') as String;
    // 发起POST请求,传入url及表单数据
    response = await dio.post(url, data: formData);
    if(response.statusCode == 200) {
      return response;
    }else{
      throw Exception(\'后端接口异常,请求检查代码和服务器运行情况...\');
    }
  }catch(e){
    return print(\'error:::${e.toString()}\');
  }
}
  1. 打开good_list_page.dart文件编写商品列表数据模型。(JSON转Model和Model转JSON)
// 商品列表数据模型
class GoodListModel{
  // 状态码
  String code;
  // 状态信息
  String message;
  // 商品列表数据
  List<GoodModel> data;
  // 通过传入json数据转换成数据模型
  GoodListModel.fromJson(Map<String, dynamic> json){
    code = json[\'code\'];
    message = json[\'message\'];
    if(json[\'data\'] != null) {
      data = List<GoodModel>();
      // 循环迭代JSON数据并将每一项数据转换成GoodModel
      json[\'data\'].forEach((v){
        data.add(GoodModel.fromJson(v));
      });
    }
  }
  // 将数据模型转换成json
  Map<String, dynamic> toJson() {
    Map<String, dynamic> data = new Map();
    data[\'code\'] = this.code;
    data[\'message\'] = this.message;
    if(this.data != null) {
      data[\'data\'] = this.data.map((e) => e.toJson()).toList();
    }
    return data;
  }
}
// 商品信息模型
class GoodModel {
  // 商品图片
  String image;
  // 原价
  String oriPrice;
  // 现有价格
  String presentPrice;
  // 商品名称
  String name;
  // 商品id
  String goodsId;
  // 构造方法
  GoodModel(
      this.image, this.oriPrice, this.presentPrice, this.name, this.goodsId);
  // 通过传入json数据转换成数据模型
  GoodModel.fromJson(Map<String, dynamic> json){
    image = json[\'image\'];
    oriPrice = json[\'oriPrice\'];
    presentPrice = json[\'presentPrice\'];
    name = json[\'name\'];
    goodsId = json[\'goodsId\'];
  }
  // 将数据模型转换成json
  Map<String, dynamic> toJson() {
    Map<String, dynamic> data = new Map();
    data[\'image\'] = this.image;
    data[\'oriPrice\'] = this.oriPrice;
    data[\'presentPrice\'] = this.presentPrice;
    data[\'name\'] = this.name;
    data[\'goodsId\'] = this.goodsId;
    return data;
  }
}
  1. 编写商品列表界面,打开good_list_page.dart文件,添加GoodListPage组件,需要继承StatefulWidget有状态组件。
import \'dart:convert\';
import \'package:flutter/material.dart\';
import \'package:flutter_dio/model/good_list_model.dart\';
import \'package:flutter_dio/service/http_service.dart\';
// 商品列表页面
class GoodListPage extends StatefulWidget {
  @override
  _GoodListPageState createState() => new _GoodListPageState();
}
class _GoodListPageState extends State<GoodListPage> {
  // 初始化数据模型
  GoodListModel goodListModel;
  // 滚动控制
  var scrollController = new ScrollController();
  @override
  initState(){
    super.initState();
    // 获取商品数据
    getGoods();
  }
  @override
  Widget build(BuildContext context) {
    // 通过商品列表判断数组长度来判断是否有数据
    if(goodListModel.data.length > 0) {
      return ListView.builder(
        // 列表长度
        itemCount: goodListModel.data.length,
        // 滚动控制器
        controller: scrollController,
        // 列表构造器
        itemBuilder: (context, index){
          return _ListWidget(goodListModel.data, index);
        },
      );
    }else{
      // 商品列表没有数据时返回空容器
      return Container();
    }
  }
  // 获取商品数据
  Future<void> getGoods() async {
    // 请求url
    var url = \'http://127.0.0.1:3000/getDioData\';
    // 请求参数,店铺Id
    var formData = {\'shopId\': \'001\'};
    // 调用请求方法传入url表单数据
    await request(url, formData:formData).then((value){
      // 返回数据进行json解码
      var data = json.decode(value.toString());
      // 打印数据
      print(\'商品数据列表Json格式:::\' + data.toString());
      // 设置状态刷新数据
      setState(() {
        // 将返回的json数据转换成Model
        goodListModel = GoodListModel.fromJson(data);
      });
    });
  }
  // 商品列表项
  Widget _ListWidget(List<GoodModel> list, int index) {
    return Container(
      padding: EdgeInsets.only(top: 5.0, bottom: 5.0),
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border(
          bottom: BorderSide(width: 1.0, color: Colors.black12),
        ),
      ),
      // 水平方向布局
      child: Row(
        children: [
          // 返回商品图片
          _goodsImage(list, index),
          SizedBox(width: 10,),
          // 右侧使用垂直布局
          Column(
            children: [
              _goodsName(list, index),
              _goodsPrice(list, index),
            ],
          ),
        ],
      ),
    );
  }
  // 商品图片
  Widget _goodsImage(List<GoodModel> list, int index) {
    return Container(
      width: 150,
      height: 150,
      child: Image.network(list[index].image, fit: BoxFit.fitWidth,),
    );
  }
  // 商品名称
  Widget _goodsName(List<GoodModel> list, int index) {
    return Container(
      padding: EdgeInsets.all(5.0),
      width: 200,
      child: Text(list[index].name, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 18),),
    );
  }
  // 商品价格
  Widget _goodsPrice(List<GoodModel> list, int index) {
    return Container(
      margin: EdgeInsets.only(top: 20.0),
      width: 200,
      child: Row(
        children: [
          Text(\'价格¥${list[index].presentPrice}\', style: TextStyle(color: Colors.red),),
          Text(\'¥${list[index].oriPrice}\'),
        ],
      ),
    );
  }
}

以上是关于03Flutter--网络请求的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

VSCode自定义代码片段14——Vue的axios网络请求封装

Flutter实现网络请求

Flutter学习-网络请求

flutter 分层数据显示 类似于第一章的第一节显示 网络请求渲染 开源代码