Flutter--FutureBuilder/StreamBuilder(待补)
futureBuilder和StreamSBuilder可以用来异步更新UI,比如我们需要请求一个server的数据,可以使用这两者来实现。
当然用StatefulWidget肯定也可以做,但这两个组件使得代码量更少,更精简。
futureBuilder源码:
class FutureBuilder<T> extends StatefulWidget { /// Creates a widget that builds itself based on the latest snapshot of /// interaction with a [Future]. /// /// The [builder] must not be null. const FutureBuilder({ Key key, this.future, this.initialData, @required this.builder, }) : assert(builder != null), super(key: key); /// The asynchronous computation to which this builder is currently connected, /// possibly null. /// /// If no future has yet completed, including in the case where [future] is /// null, the data provided to the [builder] will be set to [initialData]. final Future<T> future; /// The build strategy currently used by this builder. /// /// The builder is provided with an [AsyncSnapshot] object whose /// [AsyncSnapshot.connectionState] property will be one of the following /// values: /// /// * [ConnectionState.none]: [future] is null. The [AsyncSnapshot.data] will /// be set to [initialData], unless a future has previously completed, in /// which case the previous result persists. /// /// * [ConnectionState.waiting]: [future] is not null, but has not yet /// completed. The [AsyncSnapshot.data] will be set to [initialData], /// unless a future has previously completed, in which case the previous /// result persists. /// /// * [ConnectionState.done]: [future] is not null, and has completed. If the /// future completed successfully, the [AsyncSnapshot.data] will be set to /// the value to which the future completed. If it completed with an error, /// [AsyncSnapshot.hasError] will be true and [AsyncSnapshot.error] will be /// set to the error object. final AsyncWidgetBuilder<T> builder; /// The data that will be used to create the snapshots provided until a /// non-null [future] has completed. /// /// If the future completes with an error, the data in the [AsyncSnapshot] /// provided to the [builder] will become null, regardless of [initialData]. /// (The error itself will be available in [AsyncSnapshot.error], and /// [AsyncSnapshot.hasError] will be true.) final T initialData; @override State<FutureBuilder<T>> createState() => _FutureBuilderState<T>(); }
其中关键参数future:调用的异步函数
builder的类型是:
typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
是针对snapshot的不同状态返回不同的Widget。
snapshot的可能状态有Connection.none/waiting/done(其中done分两种,一个成功,一个报错)
具体看下面的源码:
/// The builder is provided with an [AsyncSnapshot] object whose /// [AsyncSnapshot.connectionState] property will be one of the following /// values: /// /// * [ConnectionState.none]: [future] is null. The [AsyncSnapshot.data] will /// be set to [initialData], unless a future has previously completed, in /// which case the previous result persists. /// /// * [ConnectionState.waiting]: [future] is not null, but has not yet /// completed. The [AsyncSnapshot.data] will be set to [initialData], /// unless a future has previously completed, in which case the previous /// result persists. /// /// * [ConnectionState.done]: [future] is not null, and has completed. If the /// future completed successfully, the [AsyncSnapshot.data] will be set to /// the value to which the future completed. If it completed with an error, /// [AsyncSnapshot.hasError] will be true and [AsyncSnapshot.error] will be /// set to the error object.
例子:
import 'package:flutter/cupertino.dart'; import "package:flutter/material.dart"; import 'package:flutter/rendering.dart'; import "package:flutter/src/material/dialog.dart"; import 'package:flutter/gestures.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget{ @override Widget build(BuildContext context) { return MaterialApp( title:'fuck', home: TestPage(), ); } } class TestPage extends StatefulWidget { TestPage ({Key key}): super( key :key); @override State<StatefulWidget> createState() { // TODO: implement createState return TestPageState(); } } class TestPageState extends State<TestPage> { Future<String> wait5Second() async { return Future.delayed(Duration(seconds: 5),() => "我是数据"); } @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar(title: Text('futureBuilder测试'),), body: Center( child: FutureBuilder( future: wait5Second(), builder: (BuildContext context,AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (!snapshot.hasError) { return Text('收到:${snapshot.data}'); } else { return Text('报错:${snapshot.error}'); } } else { return CircularProgressIndicator(); } }, ), )); } }
streamBuilder回头用到了再补,毕竟现在stream都没用到过。
进击的小🐴农