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