diff --git a/packages/flutter/lib/src/widgets/scroll_delegate.dart b/packages/flutter/lib/src/widgets/scroll_delegate.dart index e224750ce57..96841dbda5e 100644 --- a/packages/flutter/lib/src/widgets/scroll_delegate.dart +++ b/packages/flutter/lib/src/widgets/scroll_delegate.dart @@ -885,6 +885,13 @@ Widget _createErrorWidget(Object exception, StackTrace stackTrace) { /// * [TwoDimensionalChildListDelegate], an concrete subclass of this that /// uses a two dimensional array to layout children. abstract class TwoDimensionalChildDelegate extends ChangeNotifier { + /// Creates a delegate that supplies children for scrolling in two dimensions. + TwoDimensionalChildDelegate() { + if (kFlutterMemoryAllocationsEnabled) { + ChangeNotifier.maybeDispatchObjectCreation(this); + } + } + /// Returns the child with the given [ChildVicinity], which is described in /// terms of x and y indices. /// diff --git a/packages/flutter/test/widgets/ensure_visible_test.dart b/packages/flutter/test/widgets/ensure_visible_test.dart index 71f01386998..33cdc07eda4 100644 --- a/packages/flutter/test/widgets/ensure_visible_test.dart +++ b/packages/flutter/test/widgets/ensure_visible_test.dart @@ -7,7 +7,6 @@ import 'dart:math' as math; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'two_dimensional_utils.dart'; @@ -1063,10 +1062,7 @@ void main() { return tester.element(findKey(vicinity)); } - testWidgets('Axis.vertical', - // TODO(polina-c): RenderTwoDimensionalViewport should dispose _delegate https://github.com/flutter/flutter/issues/145628 [leaks-to-clean] - experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(), - (WidgetTester tester) async { + testWidgets('Axis.vertical', (WidgetTester tester) async { await tester.pumpWidget(simpleBuilderTest(useCacheExtent: true)); Scrollable.ensureVisible(findContext( diff --git a/packages/flutter/test/widgets/scroll_delegate_test.dart b/packages/flutter/test/widgets/scroll_delegate_test.dart new file mode 100644 index 00000000000..fc5a7ba1f92 --- /dev/null +++ b/packages/flutter/test/widgets/scroll_delegate_test.dart @@ -0,0 +1,29 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; + +void main() { + test('TwoDimensionalChildBuilderDelegate dispatches memory events', () async { + await expectLater( + await memoryEvents( + () => TwoDimensionalChildBuilderDelegate(builder: (_, __) => null).dispose(), + TwoDimensionalChildBuilderDelegate, + ), + areCreateAndDispose, + ); + }); + + test('TwoDimensionalChildListDelegate dispatches memory events', () async { + await expectLater( + await memoryEvents( + () => TwoDimensionalChildListDelegate(children: >[]).dispose(), + TwoDimensionalChildListDelegate, + ), + areCreateAndDispose, + ); + }); +} diff --git a/packages/flutter/test/widgets/two_dimensional_scroll_view_test.dart b/packages/flutter/test/widgets/two_dimensional_scroll_view_test.dart index 8bd34d7ac24..0b29d547f60 100644 --- a/packages/flutter/test/widgets/two_dimensional_scroll_view_test.dart +++ b/packages/flutter/test/widgets/two_dimensional_scroll_view_test.dart @@ -360,6 +360,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -368,7 +370,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.free, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 100, maxYIndex: 100, builder: (BuildContext context, ChildVicinity vicinity) { @@ -503,6 +505,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -511,7 +515,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.free, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 100, maxYIndex: 100, builder: (BuildContext context, ChildVicinity vicinity) { @@ -588,6 +592,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -596,7 +602,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.free, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 20, maxYIndex: 1, builder: _testChildBuilder, @@ -636,6 +642,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -644,7 +652,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.weightedEvent, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 20, maxYIndex: 1, builder: _testChildBuilder, @@ -684,6 +692,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -692,7 +702,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.weightedContinuous, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 20, maxYIndex: 1, builder: _testChildBuilder, @@ -734,6 +744,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -742,7 +754,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.free, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 1, maxYIndex: 20, builder: _testChildBuilder, @@ -782,6 +794,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -790,7 +804,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.weightedEvent, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 1, maxYIndex: 20, builder: _testChildBuilder, @@ -830,6 +844,8 @@ void main() { addTearDown(verticalController.dispose); final ScrollController horizontalController = ScrollController(); addTearDown(horizontalController.dispose); + late final TwoDimensionalChildBuilderDelegate delegate; + addTearDown(() => delegate.dispose()); await tester.pumpWidget( Directionality( @@ -838,7 +854,7 @@ void main() { verticalDetails: ScrollableDetails.vertical(controller: verticalController), horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController), diagonalDragBehavior: DiagonalDragBehavior.weightedContinuous, - delegate: TwoDimensionalChildBuilderDelegate( + delegate: delegate = TwoDimensionalChildBuilderDelegate( maxXIndex: 1, maxYIndex: 20, builder: _testChildBuilder, diff --git a/packages/flutter/test/widgets/two_dimensional_viewport_test.dart b/packages/flutter/test/widgets/two_dimensional_viewport_test.dart index bec1861402e..a3caa621250 100644 --- a/packages/flutter/test/widgets/two_dimensional_viewport_test.dart +++ b/packages/flutter/test/widgets/two_dimensional_viewport_test.dart @@ -335,6 +335,7 @@ void main() { ); } ); + addTearDown(builderDelegate.dispose); await tester.pumpWidget(simpleBuilderTest( delegate: builderDelegate,