AsyncBuilder介紹
AsyncBuilder名字起得有點(diǎn)怪,實(shí)際上它是一個(gè)Widget控件[官方文檔]鹊漠,它把異步操作與數(shù)據(jù)更新結(jié)合在一起,舉個(gè)例子登钥,以首頁(yè)為例娶靡,通常顯示首頁(yè)的時(shí)候會(huì)先判斷首頁(yè)數(shù)據(jù)拉取下來(lái)了沒(méi),沒(méi)有沒(méi)有就顯示loading结执,如果有就直接渲染首頁(yè)數(shù)據(jù)艾凯,代碼邏輯大概是這樣
if (data == null) {
fetchData();
showLoading();
} else {
showMainPage();
hideLoading();
}
可以看出來(lái)數(shù)據(jù)的獲取跟ui的更新都是分開(kāi)的,而AsyncBuilder正是把數(shù)據(jù)獲取與數(shù)據(jù)ui更新綁定在一起蜡感,在使用AsyncBuilder時(shí)我們只需要給它傳遞一個(gè)Future對(duì)象,負(fù)責(zé)數(shù)據(jù)的獲取郑兴,以及實(shí)現(xiàn)一個(gè)AsyncWidgetBuilder回調(diào)方法,負(fù)責(zé)對(duì)應(yīng)ui的創(chuàng)建顯示即可叽粹,下面具體說(shuō)說(shuō)它的用法却舀。
AsyncBuilder使用介紹
- 構(gòu)造方法
FutureBuilder({Key key, Future<T> future, T initialData, @required AsyncWidgetBuilder<T> builder })
future
: 異步io操作的Future對(duì)象
initialData
: 默認(rèn)初始化數(shù)據(jù)
builder
: 負(fù)責(zé)根據(jù)不同狀態(tài)創(chuàng)建對(duì)應(yīng)ui的方法實(shí)現(xiàn)
Future對(duì)象
future對(duì)象的創(chuàng)建必須要提前挽拔,譬如可以在 State.initState State.didUpdateConfig, 或者 State.didChangeDependencies等時(shí)期創(chuàng)建,不能在State.build 或者StatelessWidget.build回調(diào)時(shí)去創(chuàng)建啡氢,如果在創(chuàng)建FutureBuilder時(shí)同時(shí)創(chuàng)建Future术裸,那么一旦FutureBuilder的parent Widget發(fā)生變化時(shí),異步任務(wù)都會(huì)被觸發(fā)辨绊。AsyncWidgetBuilder 方法
AsyncWidgetBuilder是接受兩個(gè)參數(shù)BuildContext context
跟AsyncSnapshot<T> snapshot
并且返回一個(gè)Widget對(duì)象的方法匹表,其中AsyncSnapshot<T> snapshot
包含了異步io操作的一些信息回調(diào)袍镀,其中有:
1connectionState
:枚舉對(duì)象冻晤,它的值可以是none
waiting
active
done
2data
:異步io處理完時(shí)回調(diào)的數(shù)據(jù)
3error
:異步io處理發(fā)生錯(cuò)誤時(shí)回調(diào)
完整例子
下面給出一個(gè)完整的代碼例子,啟動(dòng)頁(yè)面的時(shí)候會(huì)先顯示Awaiting的狀態(tài)设江,同時(shí)會(huì)去請(qǐng)求百度的頁(yè)面攘轩,請(qǐng)求回來(lái)了就打印下數(shù)據(jù)
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
/**
* Created by nls on 2019/7/20.
* Nothing.
*/
class FutureBuilderDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primaryColor: Colors.blue),
home: HomeWidget());
}
}
class HomeWidget extends StatefulWidget {
@override
State createState() {
return HomeState();
}
}
class HomeState extends State<HomeWidget> {
var futureFetchData;
@override
void initState() {
super.initState();
futureFetchData = fetchData();
}
Future<String> fetchData() async {
var httpClient = new HttpClient();
var uri = Uri.parse('http://www.baidu.com');
var request = await httpClient.getUrl(uri);
var response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
return responseBody;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("futureBuilder")),
body: Container(
padding: const EdgeInsets.all(10),
child: FutureBuilder<String>(
future: futureFetchData, // a previously-obtained Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Press button to start.');
case ConnectionState.active:
case ConnectionState.waiting:
return Text('Awaiting result...');
case ConnectionState.done:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
return Text('Result: ${snapshot.data}');
}
return null; // unreachable
},
),
)
);
}
}