Skip to content

Commit 8e50a17

Browse files
Stop DropdownMenu internal scrolling from moving parent Scrollable (#153360)
fixes flutter/flutter#151854 fixes #139113 The regression test uses nested `ListView` because I could not reproduce the issue without using nested `Scrollable`. The issue is masked when there is only one `Scrollable` outside `DropdownMenu`. While `Scrollable.ensureVisible` can find all the `Scrollable`, the actual scrolling is performed by `ScrollPosition.ensureVisible` , which uses the `RenderObject` tree to find nearest Viewport but it could not find one due to `OverlayPortal` putting the target `RenderObject` at different point. So no scrolling will occur. However when there are nested `Scrollable`, `Scrollable.ensureVisible` can scroll the outside `Scrollable` normally since no `RenderObject` tree gap exist between the two `Scrollable`
1 parent e0cd56b commit 8e50a17

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

packages/flutter/lib/src/material/dropdown_menu.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
592592
WidgetsBinding.instance.addPostFrameCallback((_) {
593593
final BuildContext? highlightContext = buttonItemKeys[currentHighlight!].currentContext;
594594
if (highlightContext != null) {
595-
Scrollable.ensureVisible(highlightContext);
595+
Scrollable.of(highlightContext).position.ensureVisible(highlightContext.findRenderObject()!);
596596
}
597597
}, debugLabel: 'DropdownMenu.scrollToHighlight');
598598
}

packages/flutter/test/material/dropdown_menu_test.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2723,6 +2723,36 @@ void main() {
27232723
),
27242724
);
27252725
});
2726+
2727+
// This is a regression test for https://github.com/flutter/flutter/issues/151854.
2728+
testWidgets('scrollToHighlight does not scroll parent', (WidgetTester tester) async {
2729+
final ScrollController controller = ScrollController();
2730+
addTearDown(controller.dispose);
2731+
2732+
await tester.pumpWidget(
2733+
MaterialApp(
2734+
home: Scaffold(
2735+
body: ListView(
2736+
controller: controller,
2737+
children: <Widget>[
2738+
ListView(
2739+
shrinkWrap: true,
2740+
children: <Widget>[DropdownMenu<TestMenu>(
2741+
initialSelection: menuChildren.last.value,
2742+
dropdownMenuEntries: menuChildren,
2743+
)],
2744+
),
2745+
const SizedBox(height: 1000.0),
2746+
],
2747+
),
2748+
),
2749+
),
2750+
);
2751+
2752+
await tester.tap(find.byType(TextField).first);
2753+
await tester.pumpAndSettle();
2754+
expect(controller.offset, 0.0);
2755+
});
27262756
}
27272757

27282758
enum TestMenu {

0 commit comments

Comments
 (0)