第4节:详解Future

Flutter学习之三方库,网络库,轮播图库,下拉刷新库,跳转传值库,BaseWidght封装

Flutter的网络请求库:Dio

RefreshIndicator是Material风格的下拉刷新组件。

CupertinoSliverRefreshControl 是ios风格的下拉刷新控件。

参考文章:

1
2
3
4
5
import 'package:dio/dio.dart';

Future<String> getData() async {
return "123";
}

Flutter中的网络请求
网络请求是非常典型的异步任务,下面我们就来结合网络请求来看看Flutter中的异步是如何使用的。

网络请求的方式有很多,这里我就直接用目前比较好用的DIO网络请求库 了,你也可以使用官方文档中的网络请求 ,都是可以的。

下面我们来简单用一用网络请求。

这里我使用的聚合上的一个接口

接口地址:http://v.juhe.cn/toutiao/index?type=keji&key=4c52313fc9247e5b4176aed5ddd56ad7

关于DIO如何使用这里就不讲了,Github上文档很详细,使用起来也很简单。
下面我们直接用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'package:dio/dio.dart'; // 导包

/// 请求接口获取数据的方法
Future<Response> getData() async {
String url = "http://v.juhe.cn/toutiao/index";
String key = "4c52313fc9247e5b4176aed5ddd56ad7";
String type = "keji";

print("开始请求数据");
Response response = await Dio().get(url, queryParameters: {"type": type, "key": key});
print("请求完成");

return response;
}

注意一下几点:

网络请求是耗时操作
要使用async来标明getData这个函数是一个异步函数
await 用于等待请求返回的结果,此时会阻塞掉后面的代码,只有当请求结束后面的代码才会执行
async标注的函数其返回值类型是Future
然后我们就可以在main函数中来接收网络请求后的结果了:

1
2
3
4
5
6
7
8
9
10
11
main() {
getData().then((result) {
print("接口返回的数据是:${result}");
}).whenComplete((){
print("异步任务处理完成");
}).catchError((){
print("出现异常了");
});

print("我是在请求数据后面的代码呦!");
}

我们来看看执行的结果:

这样一来,我们就完成了Flutter中的异步操作了,可以看到,相对于原生Android来讲,Flutter中的异步是非常简单的。

Flutter 请求网络数据时显示加载中
一个很常见的需求,在首次进入页面时,此时数据还需要从网络上获取,我们希望在网络请求完成之前显示一个加载页面,请求完成之后再显示数据。此时,我们就可以使用FutureBuilder来完成了

首先是接口请求函数,为了更明显的能看到加载控件的显示,这里的异步请求函数中我延时3秒后再请求数据,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_async/widget/loading.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '新闻列表',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: '新闻列表'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _getNews(),
builder: (BuildContext context, AsyncSnapshot<Response> snapshot) {
/*表示数据成功返回*/
if (snapshot.hasData) {
Response response = snapshot.data;
return Text("${response.data.toString()}");
} else {
return LoadingWidget();
}
},
));
}
}


/**

* 请求接口获取数据
*/
Future<Response> _getNews() async {
await Future.delayed(Duration(seconds: 3), () {
print("延时三秒后请求数据");
});

String url = "http://v.juhe.cn/toutiao/index";
String key = "4c52313fc9247e5b4176aed5ddd56ad7";
String type = "keji";

print("开始请求数据");
Response response =
await Dio().get(url, queryParameters: {"type": type, "key": key});

print("请求完成");

return response;
}

运行效果:
在这里插入图片描述

下面是demo,需要的可以下载:
flutter_async Demo