展示異步任務狀態
當有一個Future(異步)任務需要展示給用戶時,可以使用FutureBuilder控制元件來完成,比如向服務器發送資料成功時顯示成功提示:
import 'package:flutter/material.dart';
class WyFutureBuilder extends StatefulWidget {
@override
_WyFutureBuilderState createState() => _WyFutureBuilderState();
}
class _WyFutureBuilderState extends State<WyFutureBuilder> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FutureBuilder'),
),
body: _creactFutureBuilder(),
);
}
var _future = Future.delayed(Duration(seconds: 5), () {
return '老王,一個有態度的程式員';
});
Widget _creactFutureBuilder() {
return FutureBuilder(
future: _future,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
var widget;
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
widget = Icon(
Icons.error,
color: Colors.red,
size: 48,
);
} else {
widget = Icon(
Icons.check_circle,
color: Colors.green,
size: 36,
);
}
} else {
widget = Padding(
padding: EdgeInsets.all(20),
child: CircularProgressIndicator(),
);
}
return Center(
child: Container(
height: 100,
width: 100,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.all(Radius.circular(10))),
child: widget,
),
);
});
}
}

在Future任務中出現例外如何處理,下面模擬出現例外,修改_future:
var _future = Future.delayed(Duration(seconds: 3), () {
return Future.error('');
});
builder是FutureBuilder的構建函式,在這里可以判斷狀態及資料顯示不同的UI,
ConnectionState的狀態包含四種:none、waiting、active、done,但我們只需要關注done狀態,此狀態表示Future執行完成,snapshot引數的型別是AsyncSnapshot<T>,
ListView加載網路資料
FutureBuilder還有一個比較常用的場景:網路加載資料并串列展示,這是一個非常常見的功能,在網路請求程序中顯示loading,請求失敗時顯示失敗UI,成功時顯示成功UI,
模擬成功網路請求,通常會回傳json字串:
var _future = Future.delayed(Duration(seconds: 3), () {
return 'json 字串';
});
//構建FutureBuilder控制元件:
Widget _createListView(){
return FutureBuilder(
future: _future,
builder: (context, snapshot) {
var widget;
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
widget = _loadingErrorWidget();
} else {
widget = _dataWidget(snapshot.data);
}
} else {
widget = _loadingWidget();
}
return widget;
});
}
//構建loading控制元件:
_loadingWidget(){
return Center(
child: Padding(
padding: EdgeInsets.all(20),
child: CircularProgressIndicator(),
),
);
}
//資料加載成功,構建資料展示控制元件:
_dataWidget(data){
return ListView.separated(itemBuilder: (context,index){
return Container(
height: 60,
alignment: Alignment.center,
child: Text('$index',style: TextStyle(fontSize: 20),),
);
},
separatorBuilder: (context,index){
return Divider();
},
itemCount: 10);
}
//構建網路加載失敗控制元件:
_loadingErrorWidget() {
return Center(
child: Text('資料加載失敗,請重試,'),
);
}

模擬網路加載失敗:
var _future = Future.delayed(Duration(seconds: 3), () {
return Future.error('');
});
通過上面的示例說明FutureBuilder控制元件極大的簡化了異步任務相關顯示的控制元件,不再需要開發者自己維護各種狀態以及更新時呼叫`State.setState`,
防止FutureBuilder重繪
FutureBuilder是一個StatefulWidget控制元件,如果在FutureBuilder控制元件節點的父節點重繪`rebuild`,那么FutureBuilder也會重繪,這不僅耗費不必要的資源,如果是網路請求還會消耗用戶的流量,這是非常糟糕的體驗,如何解決這個問題?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/394402.html
標籤:其他
上一篇:在plt中繪制日期時不均勻的網格
