• 03、Flutter网络请求


    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( 1.0, color: Colors.black12),
            ),
          ),
          // 水平方向布局
          child: Row(
            children: [
              // 返回商品图片
              _goodsImage(list, index),
              SizedBox( 10,),
              // 右侧使用垂直布局
              Column(
                children: [
                  _goodsName(list, index),
                  _goodsPrice(list, index),
                ],
              ),
            ],
          ),
        );
      }
      // 商品图片
      Widget _goodsImage(List<GoodModel> list, int index) {
        return Container(
           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),
           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),
           200,
          child: Row(
            children: [
              Text('价格¥${list[index].presentPrice}', style: TextStyle(color: Colors.red),),
              Text('¥${list[index].oriPrice}'),
            ],
          ),
        );
      }
    }
    
  • 相关阅读:
    MySql数据类型
    mysql中char,varchar,text区别
    php错误提示:date_default_timezone_get
    才储分析
    js 阻止后续事件
    大型高性能网站的十项规则
    为rand函数加入随机数种子
    php-通过共享内存实现消息队列和进程通信
    PHP比较有用的常量
    json处理内容中多双引号的情况
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14928341.html
Copyright © 2020-2023  润新知