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请求服务
- 在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()}');
}
}
- 打开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;
}
}
- 编写商品列表界面,打开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}'),
],
),
);
}
}