flutter 怎么拦截请求_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 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 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 json) => _$todayFilmBeanFromJson(json);

//bean对象转换为json

Map toJson() => _$todayFilmBeanToJson(this);

}

生成的TodayFilmBean.g.dart类是这样的

part of 'TodayFilmBean.dart';

//json转换为bean对象

TodayFilmBean _$todayFilmBeanFromJson(Map json) {

return TodayFilmBean(json['movieId'] as String,json['movieName'] as String,

json['pic_url'] as String);

}

//bean对象转换为json

Map _$todayFilmBeanToJson(TodayFilmBean instance) =>

{

'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 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: [

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值