初始狀態
)請求中狀態
)結束狀態(成功或失敗)
)以上三種現實狀況對應 AsyncSnapshot
三個狀態json
ConnectionState.none
初始態ConnectionState.waiting
請求態ConnectionState.done
完成態
snapshot.hasError
完成(異常)snapshot.hasData
完成(正常)這篇文章的主角,FutureBuilder
就是爲了解決這個問題存在的。它接收一個 Future
請求,和對應以上幾種狀況的 widget
回調。便可把數據和界面串聯起來,避免額外聲明僅用來傳遞數據用的變量。網絡
提早聲明瞭一個 _showResult
變量,以表示頁面是否觸發請求。 而且封裝了一個 _fetch()
網絡請求。async
Future<Map> _fetch() async {
return (await Dio().get("https://jsonplaceholder.typicode.com/users/1"))
.data;
}
複製代碼
請求的結果是任意的,無論是封裝好的對象,map
,list
,均可以,只要是一個 Future<T>
fetch
把這個 Future
調用安放到 FutureBuilder
的 future
參數上, 並用 _showResult
來控制什麼時候來觸發這個請求。jsonp
FutureBuilder(
future: _showResult ? _fetch() : null,
...
)
複製代碼
再把每個 Future
的結果對應的 widget
設置到 builder
參數上:ui
FutureBuilder(
...
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none: // -------- 初始態
return RaisedButton(
onPressed: () {
setState(() {
_showResult = true; // 點擊按鈕,觸發請求
});
},
child: Text("start"),
);
case ConnectionState.waiting: // -------- 請求態
return CircularProgressIndicator();
case ConnectionState.done: // -------- 完成態
if (snapshot.hasError) { // 異常
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else { // 正常
return Text(snapshot.data["name"]);
}
break;
default:
break;
}
return Container();
},
),
複製代碼
FutureBuilder
把數據請求的 Future<T>
中的數據 T
經過 Builder
的 ConnectionState
衍生出全部可能性,並在每一個可能性裏 return
一個 Widgets
。最終實現了 state -> UI 的目的spa