Skip to content

Commit af09b57

Browse files
Removes deprecated APIs from AnimationBuilder (#129657)
Removes deprecated APIs from AnimationBuilder. Resolves #129653
1 parent 51bef1b commit af09b57

File tree

2 files changed

+1
-235
lines changed

2 files changed

+1
-235
lines changed

packages/flutter/test/animation/animation_sheet_test.dart

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,60 +20,6 @@ void main() {
2020
* because [matchesGoldenFile] does not use Skia Gold in its native package.
2121
*/
2222

23-
testWidgetsWithLeakTracking('correctly records frames using display', (WidgetTester tester) async {
24-
final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
25-
26-
await tester.pumpFrames(
27-
builder.record(
28-
const _DecuplePixels(Duration(seconds: 1)),
29-
),
30-
const Duration(milliseconds: 200),
31-
const Duration(milliseconds: 100),
32-
);
33-
34-
await tester.pumpFrames(
35-
builder.record(
36-
const _DecuplePixels(Duration(seconds: 1)),
37-
recording: false,
38-
),
39-
const Duration(milliseconds: 200),
40-
const Duration(milliseconds: 100),
41-
);
42-
43-
await tester.pumpFrames(
44-
builder.record(
45-
const _DecuplePixels(Duration(seconds: 1)),
46-
),
47-
const Duration(milliseconds: 400),
48-
const Duration(milliseconds: 100),
49-
);
50-
51-
// This test verifies deprecated methods.
52-
final Widget display = await builder.display(); // ignore: deprecated_member_use
53-
await tester.binding.setSurfaceSize(builder.sheetSize()); // ignore: deprecated_member_use
54-
await tester.pumpWidget(display);
55-
56-
await expectLater(find.byWidget(display), matchesGoldenFile('test.animation_sheet_builder.records.png'));
57-
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001
58-
59-
testWidgetsWithLeakTracking('correctly wraps a row', (WidgetTester tester) async {
60-
final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
61-
62-
const Duration duration = Duration(seconds: 2);
63-
await tester.pumpFrames(
64-
builder.record(const _DecuplePixels(duration)),
65-
duration,
66-
const Duration(milliseconds: 200),
67-
);
68-
69-
// This test verifies deprecated methods.
70-
final Widget display = await builder.display(); // ignore: deprecated_member_use
71-
await tester.binding.setSurfaceSize(builder.sheetSize(maxWidth: 80)); // ignore: deprecated_member_use
72-
await tester.pumpWidget(display);
73-
74-
await expectLater(find.byWidget(display), matchesGoldenFile('test.animation_sheet_builder.wraps.png'));
75-
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/56001
76-
7723
testWidgetsWithLeakTracking('correctly records frames using collate', (WidgetTester tester) async {
7824
final AnimationSheetBuilder builder = AnimationSheetBuilder(frameSize: _DecuplePixels.size);
7925

packages/flutter_test/lib/src/animation_sheet.dart

Lines changed: 1 addition & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:math' as math;
65
import 'dart:ui' as ui;
76

87
import 'package:flutter/foundation.dart';
@@ -136,7 +135,7 @@ class AnimationSheetBuilder {
136135
/// The frame is only recorded if the `recording` argument is true, or during
137136
/// a procedure that is wrapped within [recording]. In either case, the
138137
/// painted result of each frame will be stored and later available for
139-
/// [display]. If neither condition is met, the frames are not recorded, which
138+
/// [collate]. If neither condition is met, the frames are not recorded, which
140139
/// is useful during setup phases.
141140
///
142141
/// The `child` must not be null.
@@ -158,113 +157,6 @@ class AnimationSheetBuilder {
158157
);
159158
}
160159

161-
/// Constructs a widget that renders the recorded frames in an animation sheet.
162-
///
163-
/// The resulting widget takes as much space as its parent allows, which is
164-
/// usually the screen size. It is then filled with all recorded frames, each
165-
/// having a size specified by [frameSize], chronologically from top-left to
166-
/// bottom-right in a row-major order.
167-
///
168-
/// This widget does not check whether its size fits all recorded frames.
169-
/// Having too many frames can cause overflow errors, while having too few can
170-
/// waste the size of golden files. Therefore you should usually adjust the
171-
/// viewport size to [sheetSize] before calling this method.
172-
///
173-
/// The `key` is applied to the root widget.
174-
///
175-
/// This method can only be called if at least one frame has been recorded.
176-
///
177-
/// The [display] is the legacy way of acquiring the output for comparison.
178-
/// It is not recommended because it requires more boilerplate, and produces
179-
/// a much large image than necessary: each pixel is rendered in 3x3 pixels
180-
/// without higher definition. Use [collate] instead.
181-
///
182-
/// Using this way includes the following steps:
183-
///
184-
/// * Create an instance of this class.
185-
/// * Pump frames that render the target widget wrapped in [record]. Every frame
186-
/// that has `recording` being true will be recorded.
187-
/// * Adjust the size of the test viewport to the [sheetSize] (see the
188-
/// documentation of [sheetSize] for more information).
189-
/// * Pump a frame that renders [display], which shows all recorded frames in an
190-
/// animation sheet, and can be matched against the golden test.
191-
///
192-
/// {@tool snippet}
193-
/// The following example shows how to record an animation sheet of an [InkWell]
194-
/// being pressed then released.
195-
///
196-
/// ```dart
197-
/// testWidgets('Inkwell animation sheet', (WidgetTester tester) async {
198-
/// // Create instance
199-
/// final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(48, 24));
200-
///
201-
/// final Widget target = Material(
202-
/// child: Directionality(
203-
/// textDirection: TextDirection.ltr,
204-
/// child: InkWell(
205-
/// splashColor: Colors.blue,
206-
/// onTap: () {},
207-
/// ),
208-
/// ),
209-
/// );
210-
///
211-
/// // Optional: setup before recording (`recording` is false)
212-
/// await tester.pumpWidget(animationSheet.record(
213-
/// target,
214-
/// recording: false,
215-
/// ));
216-
///
217-
/// final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(InkWell)));
218-
///
219-
/// // Start recording (`recording` is true)
220-
/// await tester.pumpFrames(animationSheet.record(
221-
/// target,
222-
/// recording: true,
223-
/// ), const Duration(seconds: 1));
224-
///
225-
/// await gesture.up();
226-
///
227-
/// await tester.pumpFrames(animationSheet.record(
228-
/// target,
229-
/// recording: true,
230-
/// ), const Duration(seconds: 1));
231-
///
232-
/// // Adjust view port size
233-
/// tester.binding.setSurfaceSize(animationSheet.sheetSize());
234-
///
235-
/// // Display
236-
/// final Widget display = await animationSheet.display();
237-
/// await tester.pumpWidget(display);
238-
///
239-
/// // Compare against golden file
240-
/// await expectLater(
241-
/// find.byWidget(display),
242-
/// matchesGoldenFile('inkwell.press.animation.png'),
243-
/// );
244-
/// }, skip: isBrowser); // Animation sheet does not support browser https://github.com/flutter/flutter/issues/56001
245-
/// ```
246-
/// {@end-tool}
247-
@Deprecated(
248-
'Use AnimationSheetBuilder.collate instead. '
249-
'This feature was deprecated after v2.3.0-13.0.pre.',
250-
)
251-
Future<Widget> display({Key? key}) async {
252-
assert(_recordedFrames.isNotEmpty);
253-
final List<ui.Image> frames = await _frames;
254-
return _CellSheet(
255-
key: key,
256-
cellSize: frameSize,
257-
children: frames.map((ui.Image image) => RawImage(
258-
image: image.clone(),
259-
width: frameSize.width,
260-
height: frameSize.height,
261-
// Disable quality enhancement because the point of this class is to
262-
// precisely record what the widget looks like.
263-
filterQuality: ui.FilterQuality.none,
264-
)).toList(),
265-
);
266-
}
267-
268160
/// Returns an result image by putting all frames together in a table.
269161
///
270162
/// This method returns a table of captured frames, `cellsPerRow` images
@@ -277,39 +169,6 @@ class AnimationSheetBuilder {
277169
'No frames are collected. Have you forgot to set `recording` to true?');
278170
return _collateFrames(frames, frameSize, cellsPerRow);
279171
}
280-
281-
/// Returns the smallest size that can contain all recorded frames.
282-
///
283-
/// This is used to adjust the viewport during unit tests, i.e. the size of
284-
/// virtual screen. Having too many frames recorded than the default viewport
285-
/// size can contain will lead to overflow errors, while having too few frames
286-
/// means the golden file might be larger than necessary.
287-
///
288-
/// The [sheetSize] returns the smallest possible size by placing the
289-
/// recorded frames, each of which has a size specified by [frameSize], in a
290-
/// row-major grid with a maximum width specified by `maxWidth`, and returns
291-
/// the size of that grid.
292-
///
293-
/// Setting the viewport size during a widget test usually involves
294-
/// [TestWidgetsFlutterBinding.setSurfaceSize] and [WidgetTester.binding].
295-
///
296-
/// The `maxWidth` defaults to the width of the default viewport, 800.0.
297-
///
298-
/// This method can only be called if at least one frame has been recorded.
299-
@Deprecated(
300-
'The `sheetSize` is only useful for `display`, which should be migrated to `collate`. '
301-
'This feature was deprecated after v2.3.0-13.0.pre.',
302-
)
303-
Size sheetSize({double maxWidth = _kDefaultTestViewportWidth}) {
304-
assert(_recordedFrames.isNotEmpty);
305-
final int cellsPerRow = (maxWidth / frameSize.width).floor();
306-
final int rowNum = (_recordedFrames.length / cellsPerRow).ceil();
307-
final double width = math.min(cellsPerRow, _recordedFrames.length) * frameSize.width;
308-
return Size(width, frameSize.height * rowNum);
309-
}
310-
311-
// The width of _kDefaultTestViewportSize in [TestViewConfiguration].
312-
static const double _kDefaultTestViewportWidth = 800.0;
313172
}
314173

315174
typedef _RecordedHandler = void Function(Future<ui.Image> image);
@@ -446,45 +305,6 @@ Future<ui.Image> _collateFrames(List<ui.Image> frames, Size frameSize, int cells
446305
return image;
447306
}
448307

449-
// Layout children in a grid of fixed-sized cells.
450-
//
451-
// The sheet fills up as much space as the parent allows. The cells are
452-
// positioned from top left to bottom right in a row-major order.
453-
class _CellSheet extends StatelessWidget {
454-
_CellSheet({
455-
super.key,
456-
required this.cellSize,
457-
required this.children,
458-
}) : assert(children.isNotEmpty);
459-
460-
final Size cellSize;
461-
final List<Widget> children;
462-
463-
@override
464-
Widget build(BuildContext context) {
465-
return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
466-
final double rowWidth = constraints.biggest.width;
467-
final int cellsPerRow = (rowWidth / cellSize.width).floor();
468-
final List<Widget> rows = <Widget>[];
469-
for (int rowStart = 0; rowStart < children.length; rowStart += cellsPerRow) {
470-
final Iterable<Widget> rowTargets = children.sublist(rowStart, math.min(rowStart + cellsPerRow, children.length));
471-
rows.add(Row(
472-
textDirection: TextDirection.ltr,
473-
children: rowTargets.map((Widget target) => SizedBox.fromSize(
474-
size: cellSize,
475-
child: target,
476-
)).toList(),
477-
));
478-
}
479-
return Column(
480-
textDirection: TextDirection.ltr,
481-
crossAxisAlignment: CrossAxisAlignment.start,
482-
children: rows,
483-
);
484-
});
485-
}
486-
}
487-
488308
class _RenderRootableRepaintBoundary extends RenderRepaintBoundary {
489309
// Like [toImage], but captures an image of all layers (composited by
490310
// RenderView and its children) clipped by the region of this object.

0 commit comments

Comments
 (0)