Unverified Commit 12e6ff2c authored by Polina Cherkasova's avatar Polina Cherkasova Committed by GitHub

DropdownRoutePage should dispose the created ScrollController. (#133941)

parent aca91df6
...@@ -102,9 +102,11 @@ class _DropdownMenuItemButton<T> extends StatefulWidget { ...@@ -102,9 +102,11 @@ class _DropdownMenuItemButton<T> extends StatefulWidget {
required this.constraints, required this.constraints,
required this.itemIndex, required this.itemIndex,
required this.enableFeedback, required this.enableFeedback,
required this.scrollController,
}); });
final _DropdownRoute<T> route; final _DropdownRoute<T> route;
final ScrollController scrollController;
final EdgeInsets? padding; final EdgeInsets? padding;
final Rect buttonRect; final Rect buttonRect;
final BoxConstraints constraints; final BoxConstraints constraints;
...@@ -131,7 +133,7 @@ class _DropdownMenuItemButtonState<T> extends State<_DropdownMenuItemButton<T>> ...@@ -131,7 +133,7 @@ class _DropdownMenuItemButtonState<T> extends State<_DropdownMenuItemButton<T>>
widget.constraints.maxHeight, widget.constraints.maxHeight,
widget.itemIndex, widget.itemIndex,
); );
widget.route.scrollController!.animateTo( widget.scrollController.animateTo(
menuLimits.scrollOffset, menuLimits.scrollOffset,
curve: Curves.easeInOut, curve: Curves.easeInOut,
duration: const Duration(milliseconds: 100), duration: const Duration(milliseconds: 100),
...@@ -205,6 +207,7 @@ class _DropdownMenu<T> extends StatefulWidget { ...@@ -205,6 +207,7 @@ class _DropdownMenu<T> extends StatefulWidget {
this.dropdownColor, this.dropdownColor,
required this.enableFeedback, required this.enableFeedback,
this.borderRadius, this.borderRadius,
required this.scrollController,
}); });
final _DropdownRoute<T> route; final _DropdownRoute<T> route;
...@@ -214,6 +217,7 @@ class _DropdownMenu<T> extends StatefulWidget { ...@@ -214,6 +217,7 @@ class _DropdownMenu<T> extends StatefulWidget {
final Color? dropdownColor; final Color? dropdownColor;
final bool enableFeedback; final bool enableFeedback;
final BorderRadius? borderRadius; final BorderRadius? borderRadius;
final ScrollController scrollController;
@override @override
_DropdownMenuState<T> createState() => _DropdownMenuState<T>(); _DropdownMenuState<T> createState() => _DropdownMenuState<T>();
...@@ -264,6 +268,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> { ...@@ -264,6 +268,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
constraints: widget.constraints, constraints: widget.constraints,
itemIndex: itemIndex, itemIndex: itemIndex,
enableFeedback: widget.enableFeedback, enableFeedback: widget.enableFeedback,
scrollController: widget.scrollController,
), ),
]; ];
...@@ -304,7 +309,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> { ...@@ -304,7 +309,7 @@ class _DropdownMenuState<T> extends State<_DropdownMenu<T>> {
platform: Theme.of(context).platform, platform: Theme.of(context).platform,
), ),
child: PrimaryScrollController( child: PrimaryScrollController(
controller: widget.route.scrollController!, controller: widget.scrollController,
child: Scrollbar( child: Scrollbar(
thumbVisibility: true, thumbVisibility: true,
child: ListView( child: ListView(
...@@ -447,7 +452,6 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> { ...@@ -447,7 +452,6 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
final BorderRadius? borderRadius; final BorderRadius? borderRadius;
final List<double> itemHeights; final List<double> itemHeights;
ScrollController? scrollController;
@override @override
Duration get transitionDuration => _kDropdownMenuDuration; Duration get transitionDuration => _kDropdownMenuDuration;
...@@ -572,7 +576,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> { ...@@ -572,7 +576,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
} }
} }
class _DropdownRoutePage<T> extends StatelessWidget { class _DropdownRoutePage<T> extends StatefulWidget {
const _DropdownRoutePage({ const _DropdownRoutePage({
super.key, super.key,
required this.route, required this.route,
...@@ -603,8 +607,15 @@ class _DropdownRoutePage<T> extends StatelessWidget { ...@@ -603,8 +607,15 @@ class _DropdownRoutePage<T> extends StatelessWidget {
final BorderRadius? borderRadius; final BorderRadius? borderRadius;
@override @override
Widget build(BuildContext context) { State<_DropdownRoutePage<T>> createState() => _DropdownRoutePageState<T>();
assert(debugCheckHasDirectionality(context)); }
class _DropdownRoutePageState<T> extends State<_DropdownRoutePage<T>> {
late ScrollController _scrollSontroller;
@override
void initState(){
super.initState();
// Computing the initialScrollOffset now, before the items have been laid // Computing the initialScrollOffset now, before the items have been laid
// out. This only works if the item heights are effectively fixed, i.e. either // out. This only works if the item heights are effectively fixed, i.e. either
...@@ -612,20 +623,25 @@ class _DropdownRoutePage<T> extends StatelessWidget { ...@@ -612,20 +623,25 @@ class _DropdownRoutePage<T> extends StatelessWidget {
// and all of the items' intrinsic heights are less than kMinInteractiveDimension. // and all of the items' intrinsic heights are less than kMinInteractiveDimension.
// Otherwise the initialScrollOffset is just a rough approximation based on // Otherwise the initialScrollOffset is just a rough approximation based on
// treating the items as if their heights were all equal to kMinInteractiveDimension. // treating the items as if their heights were all equal to kMinInteractiveDimension.
if (route.scrollController == null) { final _MenuLimits menuLimits = widget.route.getMenuLimits(widget.buttonRect, widget.constraints.maxHeight, widget.selectedIndex);
final _MenuLimits menuLimits = route.getMenuLimits(buttonRect, constraints.maxHeight, selectedIndex); _scrollSontroller = ScrollController(initialScrollOffset: menuLimits.scrollOffset);
route.scrollController = ScrollController(initialScrollOffset: menuLimits.scrollOffset);
} }
@override
Widget build(BuildContext context) {
assert(debugCheckHasDirectionality(context));
final TextDirection? textDirection = Directionality.maybeOf(context); final TextDirection? textDirection = Directionality.maybeOf(context);
final Widget menu = _DropdownMenu<T>( final Widget menu = _DropdownMenu<T>(
route: route, route: widget.route,
padding: padding.resolve(textDirection), padding: widget.padding.resolve(textDirection),
buttonRect: buttonRect, buttonRect: widget.buttonRect,
constraints: constraints, constraints: widget.constraints,
dropdownColor: dropdownColor, dropdownColor: widget.dropdownColor,
enableFeedback: enableFeedback, enableFeedback: widget.enableFeedback,
borderRadius: borderRadius, borderRadius: widget.borderRadius,
scrollController: _scrollSontroller,
); );
return MediaQuery.removePadding( return MediaQuery.removePadding(
...@@ -638,16 +654,22 @@ class _DropdownRoutePage<T> extends StatelessWidget { ...@@ -638,16 +654,22 @@ class _DropdownRoutePage<T> extends StatelessWidget {
builder: (BuildContext context) { builder: (BuildContext context) {
return CustomSingleChildLayout( return CustomSingleChildLayout(
delegate: _DropdownMenuRouteLayout<T>( delegate: _DropdownMenuRouteLayout<T>(
buttonRect: buttonRect, buttonRect: widget.buttonRect,
route: route, route: widget.route,
textDirection: textDirection, textDirection: textDirection,
), ),
child: capturedThemes.wrap(menu), child: widget.capturedThemes.wrap(menu),
); );
}, },
), ),
); );
} }
@override
void dispose() {
_scrollSontroller.dispose();
super.dispose();
}
} }
// This widget enables _DropdownRoute to look up the sizes of // This widget enables _DropdownRoute to look up the sizes of
......
...@@ -6,6 +6,7 @@ import 'package:flutter/gestures.dart' show DragStartBehavior; ...@@ -6,6 +6,7 @@ import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'data_table_test_utils.dart'; import 'data_table_test_utils.dart';
...@@ -66,7 +67,7 @@ class TestDataSource extends DataTableSource { ...@@ -66,7 +67,7 @@ class TestDataSource extends DataTableSource {
void main() { void main() {
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
testWidgets('PaginatedDataTable paging', (WidgetTester tester) async { testWidgetsWithLeakTracking('PaginatedDataTable paging', (WidgetTester tester) async {
final TestDataSource source = TestDataSource(); final TestDataSource source = TestDataSource();
addTearDown(source.dispose); addTearDown(source.dispose);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment