frameBuilder property

ImageFrameBuilder? frameBuilder
final

A builder function responsible for creating the widget that represents this image.

If this is null, this widget will display an image that is painted as soon as the first image frame is available (and will appear to "pop" in if it becomes available asynchronously). Callers might use this builder to add effects to the image (such as fading the image in when it becomes available) or to display a placeholder widget while the image is loading.

To have finer-grained control over the way that an image's loading progress is communicated to the user, see loadingBuilder.

Chaining with loadingBuilder

If a loadingBuilder has also been specified for an image, the two builders will be chained together: the result of this builder will be passed as the child argument to the loadingBuilder. For example, consider the following builders used in conjunction:

Image(
  image: _image,
  frameBuilder: (BuildContext context, Widget child, int? frame, bool? wasSynchronouslyLoaded) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: child,
    );
  },
  loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
    return Center(child: child);
  },
)

In this example, the widget hierarchy will contain the following:

Center(
  child: Padding(
    padding: const EdgeInsets.all(8.0),
    child: image,
  ),
),

{@tool dartpad --template=stateless_widget_material}

The following sample demonstrates how to use this builder to implement an image that fades in once it's been loaded.

This sample contains a limited subset of the functionality that the FadeInImage widget provides out of the box.

@override
Widget build(BuildContext context) {
  return DecoratedBox(
    decoration: BoxDecoration(
      color: Colors.white,
      border: Border.all(),
      borderRadius: BorderRadius.circular(20),
    ),
    child: Image.network(
      'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
      frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
        if (wasSynchronouslyLoaded) {
          return child;
        }
        return AnimatedOpacity(
          child: child,
          opacity: frame == null ? 0 : 1,
          duration: const Duration(seconds: 1),
          curve: Curves.easeOut,
        );
      },
    ),
  );
}

{@end-tool}

Implementation

// ignore: lines_longer_than_80_chars
///   frameBuilder: (BuildContext context, Widget child, int frame, bool wasSynchronouslyLoaded) {
///     return Padding(
///       padding: EdgeInsets.all(8.0),
///       child: child,
///     );
///   },
// ignore: lines_longer_than_80_chars
///   loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
///     return Center(child: child);
///   },
/// )
/// ```
///
/// In this example, the widget hierarchy will contain the following:
///
/// ```dart
/// Center(
///   Padding(
///     padding: EdgeInsets.all(8.0),
///     child: <image>,
///   ),
/// )
/// ```
/// {@endtemplate}
///
/// {@tool dartpad --template=stateless_widget_material}
///
/// The following sample demonstrates how to use this builder to implement an
/// image that fades in once it's been loaded.
///
/// This sample contains a limited subset of the functionality that the
/// [FadeInImage] widget provides out of the box.
///
/// ```dart
/// @override
/// Widget build(BuildContext context) {
///   return DecoratedBox(
///     decoration: BoxDecoration(
///       color: Colors.white,
///       border: Border.all(),
///       borderRadius: BorderRadius.circular(20),
///     ),
///     child: Image.network(
///       'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
// ignore: lines_longer_than_80_chars
///       frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
///         if (wasSynchronouslyLoaded) {
///           return child;
///         }
///         return AnimatedOpacity(
///           child: child,
///           opacity: frame == null ? 0 : 1,
///           duration: const Duration(seconds: 1),
///           curve: Curves.easeOut,
///         );
///       },
///     ),
///   );
/// }
/// ```
/// {@end-tool}
final ImageFrameBuilder? frameBuilder;