FutureBuilder<T> class

A widget that builds itself based on the latest snapshot of interaction with a Future.

Managing the future

The future must have been obtained earlier, e.g. during State.initState, State.didUpdateWidget, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.

A general guideline is to assume that every build method could get called every frame, and to treat omitted calls as an optimization.

Timing

Widget rebuilding is scheduled by the completion of the future, using State.setState, but is otherwise decoupled from the timing of the future. The builder callback is called at the discretion of the Flutter pipeline, and will thus receive a timing-dependent sub-sequence of the snapshots that represent the interaction with the future.

A side-effect of this is that providing a new but already-completed future to a FutureBuilder will result in a single frame in the ConnectionState.waiting state. This is because there is no way to synchronously determine that a Future has already completed.

Builder contract

For a future that completes successfully with data, assuming initialData is null, the builder will be called with either both or only the latter of the following snapshots:

  • AsyncSnapshot<String>.withData(ConnectionState.waiting, null)
  • AsyncSnapshot<String>.withData(ConnectionState.done, 'some data')

If that same future instead completed with an error, the builder would be called with either both or only the latter of:

  • AsyncSnapshot<String>.withData(ConnectionState.waiting, null)
  • AsyncSnapshot<String>.withError(ConnectionState.done, 'some error', someStackTrace)

The initial snapshot data can be controlled by specifying initialData. You would use this facility to ensure that if the builder is invoked before the future completes, the snapshot carries data of your choice rather than the default null value.

The data and error fields of the snapshot change only as the connection state field transitions from waiting to done, and they will be retained when changing the FutureBuilder configuration to another future. If the old future has already completed successfully with data as above, changing configuration to a new future results in snapshot pairs of the form:

  • AsyncSnapshot<String>.withData(ConnectionState.none, 'data of first future')
  • AsyncSnapshot<String>.withData(ConnectionState.waiting, 'data of second future')

In general, the latter will be produced only when the new future is non-null, and the former only when the old future is non-null.

A FutureBuilder behaves identically to a StreamBuilder configured with future?.asStream(), except that snapshots with ConnectionState.active may appear for the latter, depending on how the stream is implemented.

This sample shows a FutureBuilder that displays a loading spinner while it loads data. It displays a success icon and text if the Future completes with a result, or an error icon and text if the Future completes with an error. Assume the _calculation field is set by pressing a button elsewhere in the UI.
link

To create a local project with this code sample, run:
flutter create --sample=widgets.FutureBuilder.1 mysample

Inheritance

Constructors

FutureBuilder({Key? key, required Future<T>? future, T? initialData, required AsyncWidgetBuilder<T> builder})
Creates a widget that builds itself based on the latest snapshot of interaction with a Future.
const

Properties

builder AsyncWidgetBuilder<T>
The build strategy currently used by this builder.
final
future Future<T>?
The asynchronous computation to which this builder is currently connected, possibly null.
final
hashCode int
The hash code for this object.
no setterinherited
initialData → T?
The data that will be used to create the snapshots provided until a non-null future has completed.
final
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<FutureBuilder<T>>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited

Static Properties

debugRethrowError bool
Whether the latest error received by the asynchronous computation should be rethrown or swallowed. This property is useful for debugging purposes.
getter/setter pair