Fix keyboard cover SearchAnchor list results (#165382)

Fix https://github.com/flutter/flutter/issues/159261

We can leverage `MediaQuery.viewInsets` to handle this case. Once the
keyboard prompts and covers the SearchAnchor suggestion list, it will
need a bottom padding equivalent to
`MediaQuery.viewInsetsOf(context).bottom` so that it's possible to view
the whole list.

| before | after |
| --------------- | --------------- |
<video
src="https://github.com/user-attachments/assets/38a1c343-e3eb-4e42-a523-eef9fb4d5dbc"/>
| <video
src="https://github.com/user-attachments/assets/533aeca4-08c1-494f-9d47-3775ed9157d0"/>


## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Signed-off-by: huycozy <huy@nevercode.io>
This commit is contained in:
Huy 2025-04-19 06:49:25 +07:00 committed by GitHub
parent 8785fb357d
commit 00863d66bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 0 deletions

View File

@ -1146,6 +1146,9 @@ class _ViewContentState extends State<_ViewContent> {
context: context,
removeTop: true,
child: ListView(
padding: EdgeInsets.only(
bottom: MediaQuery.viewInsetsOf(context).bottom,
),
shrinkWrap: effectiveShrinkWrap,
children: result.toList(),
),

View File

@ -4058,6 +4058,47 @@ void main() {
await tester.pump();
expect(searchViewState, 'Closed');
});
testWidgets(
'The last element of the suggestion list should be visible when scrolling to the end of list',
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: SearchAnchor.bar(
suggestionsBuilder: (BuildContext context, SearchController controller) {
return List<Widget>.generate(30, (int index) {
return ListTile(
titleAlignment: ListTileTitleAlignment.center,
title: Text('Item $index'),
);
});
},
),
),
);
// Open search view.
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
const double fakeKeyboardHeight = 500.0;
final double physicalBottomPadding = fakeKeyboardHeight * tester.view.devicePixelRatio;
// Simulate the keyboard opening resizing the view.
tester.view.viewInsets = FakeViewPadding(bottom: physicalBottomPadding);
addTearDown(tester.view.reset);
// Scroll down to the end of the list.
expect(find.byType(ListView), findsOne);
await tester.fling(find.byType(ListView), const Offset(0, -5000), 5000);
await tester.pumpAndSettle();
// The last item should not be hidden by the keyboard.
final double lastItemBottom = tester.getRect(find.text('Item 29')).bottom;
final double fakeKeyboardTop =
tester.getSize(find.byType(MaterialApp)).height - fakeKeyboardHeight;
expect(lastItemBottom, lessThanOrEqualTo(fakeKeyboardTop));
},
);
}
Future<void> checkSearchBarDefaults(