diff --git a/packages/flutter/lib/src/widgets/async.dart b/packages/flutter/lib/src/widgets/async.dart index a3cda3ab050..86393f8c5f3 100644 --- a/packages/flutter/lib/src/widgets/async.dart +++ b/packages/flutter/lib/src/widgets/async.dart @@ -36,14 +36,14 @@ import 'framework.dart'; /// termination by overriding [afterDone]. Finally, the summary may be updated /// on change of stream by overriding [afterDisconnected] and [afterConnected]. /// -/// [T] is the type of stream events. +/// `T` is the type of stream events. /// -/// [S] is the type of interaction summary. +/// `S` is the type of interaction summary. /// /// See also: /// -/// * [StreamBuilder], which is specialized to the case where only the most -/// recent interaction is needed for widget building. +/// * [StreamBuilder], which is specialized for the case where only the most +/// recent interaction is needed for widget building. abstract class StreamBuilderBase extends StatefulWidget { /// Creates a [StreamBuilderBase] connected to the specified [stream]. const StreamBuilderBase({ Key key, this.stream }) : super(key: key); @@ -286,9 +286,9 @@ class AsyncSnapshot { /// See also: /// /// * [StreamBuilder], which delegates to an [AsyncWidgetBuilder] to build -/// itself based on a snapshot from interacting with a [Stream]. +/// itself based on a snapshot from interacting with a [Stream]. /// * [FutureBuilder], which delegates to an [AsyncWidgetBuilder] to build -/// itself based on a snapshot from interacting with a [Future]. +/// itself based on a snapshot from interacting with a [Future]. typedef AsyncWidgetBuilder = Widget Function(BuildContext context, AsyncSnapshot snapshot); /// Widget that builds itself based on the latest snapshot of interaction with @@ -333,14 +333,9 @@ typedef AsyncWidgetBuilder = Widget Function(BuildContext context, AsyncSnaps /// state is `ConnectionState.active`. /// /// 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 first event arrives on the stream, the snapshot carries data of -/// your choice rather than the default null value. -/// -/// See also: -/// -/// * [StreamBuilderBase], which supports widget building based on a computation -/// that spans all interactions made with the stream. +/// This should be used to ensure that the first frame has the expected value, +/// as the builder will always be called before the stream listener has a chance +/// to be processed. /// /// {@tool sample} /// @@ -365,25 +360,41 @@ typedef AsyncWidgetBuilder = Widget Function(BuildContext context, AsyncSnaps /// ) /// ``` /// {@end-tool} -// TODO(ianh): remove unreachable code above once https://github.com/dart-lang/linter/issues/1141 is fixed +/// +/// See also: +/// +/// * [ValueListenableBuilder], which wraps a [ValueListenable] instead of a +/// [Stream]. +/// * [StreamBuilderBase], which supports widget building based on a computation +/// that spans all interactions made with the stream. +// TODO(ianh): remove unreachable code above once https://github.com/dart-lang/linter/issues/1139 is fixed class StreamBuilder extends StreamBuilderBase> { /// Creates a new [StreamBuilder] that builds itself based on the latest /// snapshot of interaction with the specified [stream] and whose build - /// strategy is given by [builder]. The [initialData] is used to create the - /// initial snapshot. It is null by default. + /// strategy is given by [builder]. + /// + /// The [initialData] is used to create the initial snapshot. + /// + /// The [builder] must not be null. const StreamBuilder({ Key key, this.initialData, Stream stream, @required this.builder - }) - : assert(builder != null), - super(key: key, stream: stream); + }) : assert(builder != null), + super(key: key, stream: stream); - /// The build strategy currently used by this builder. Cannot be null. + /// The build strategy currently used by this builder. final AsyncWidgetBuilder builder; - /// The data that will be used to create the initial snapshot. Null by default. + /// The data that will be used to create the initial snapshot. + /// + /// Providing this value (presumably obtained sychronously somehow when the + /// [Stream] was created) ensures that the first frame will show useful data. + /// Otherwise, the first frame will be built with the value null, regardless + /// of whether a value is available on the stream: since streams are + /// asynchronous, no events from the stream can be obtained before the initial + /// build. final T initialData; @override