display method Null safety

  1. @Deprecated('Use AnimationSheetBuilder.collate instead. ' 'This feature was deprecated after v2.3.0-13.0.pre.')
Future<Widget> display(
  1. {Key? key}
)
@Deprecated('Use AnimationSheetBuilder.collate instead. ' 'This feature was deprecated after v2.3.0-13.0.pre.')

Constructs a widget that renders the recorded frames in an animation sheet.

The resulting widget takes as much space as its parent allows, which is usually the screen size. It is then filled with all recorded frames, each having a size specified by frameSize, chronologically from top-left to bottom-right in a row-major order.

This widget does not check whether its size fits all recorded frames. Having too many frames can cause overflow errors, while having too few can waste the size of golden files. Therefore you should usually adjust the viewport size to sheetSize before calling this method.

The key is applied to the root widget.

This method can only be called if at least one frame has been recorded.

The display is the legacy way of acquiring the output for comparison. It is not recommended because it requires more boilerplate, and produces a much large image than necessary: each pixel is rendered in 3x3 pixels without higher definition. Use collate instead.

Using this way includes the following steps:

  • Create an instance of this class.
  • Pump frames that render the target widget wrapped in record. Every frame that has recording being true will be recorded.
  • Adjust the size of the test viewport to the sheetSize (see the documentation of sheetSize for more information).
  • Pump a frame that renders display, which shows all recorded frames in an animation sheet, and can be matched against the golden test.

The following example shows how to record an animation sheet of an InkWell being pressed then released.
testWidgets('Inkwell animation sheet', (WidgetTester tester) async {
  // Create instance
  final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(48, 24));

  final Widget target = Material(
    child: Directionality(
      textDirection: TextDirection.ltr,
      child: InkWell(
        splashColor: Colors.blue,
        onTap: () {},
      ),
    ),
  );

  // Optional: setup before recording (`recording` is false)
  await tester.pumpWidget(animationSheet.record(
    target,
    recording: false,
  ));

  final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(InkWell)));

  // Start recording (`recording` is true)
  await tester.pumpFrames(animationSheet.record(
    target,
    recording: true,
  ), const Duration(seconds: 1));

  await gesture.up();

  await tester.pumpFrames(animationSheet.record(
    target,
    recording: true,
  ), const Duration(seconds: 1));

  // Adjust view port size
  tester.binding.setSurfaceSize(animationSheet.sheetSize());

  // Display
  final Widget display = await animationSheet.display();
  await tester.pumpWidget(display);

  // Compare against golden file
  await expectLater(
    find.byWidget(display),
    matchesGoldenFile('inkwell.press.animation.png'),
  );
}, skip: isBrowser); // Animation sheet does not support browser https://github.com/flutter/flutter/issues/56001

Implementation

@Deprecated(
  'Use AnimationSheetBuilder.collate instead. '
  'This feature was deprecated after v2.3.0-13.0.pre.',
)
Future<Widget> display({Key? key}) async {
  assert(_recordedFrames.isNotEmpty);
  final List<ui.Image> frames = await _frames;
  return _CellSheet(
    key: key,
    cellSize: frameSize,
    children: frames.map((ui.Image image) => RawImage(
      image: image.clone(),
      width: frameSize.width,
      height: frameSize.height,
      // Disable quality enhancement because the point of this class is to
      // precisely record what the widget looks like.
      filterQuality: ui.FilterQuality.none,
    )).toList(),
  );
}