mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Close the search by pressing escape (#167648)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> Close [showSearch()](https://api.flutter.dev/flutter/material/showSearch.html) by pressing escape button. feat #148146 ## 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 --------- Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
This commit is contained in:
parent
c0c12a759e
commit
293c2c2f10
@ -344,6 +344,15 @@ abstract class SearchDelegate<T> {
|
||||
..pop(result);
|
||||
}
|
||||
|
||||
/// Closes the search page and returns to the underlying route whitout result.
|
||||
void _pop(BuildContext context) {
|
||||
_currentBody = null;
|
||||
_focusNode?.unfocus();
|
||||
Navigator.of(context)
|
||||
..popUntil((Route<dynamic> route) => route == _route)
|
||||
..pop();
|
||||
}
|
||||
|
||||
/// The hint text that is shown in the search field when it is empty.
|
||||
///
|
||||
/// If this value is set to null, the value of
|
||||
@ -506,7 +515,16 @@ class _SearchPage<T> extends StatefulWidget {
|
||||
class _SearchPageState<T> extends State<_SearchPage<T>> {
|
||||
// This node is owned, but not hosted by, the search page. Hosting is done by
|
||||
// the text field.
|
||||
FocusNode focusNode = FocusNode();
|
||||
late final FocusNode focusNode = FocusNode(
|
||||
onKeyEvent: (FocusNode node, KeyEvent event) {
|
||||
// When the user presses the escape key, close the search page.
|
||||
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.escape) {
|
||||
widget.delegate._pop(context);
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
return KeyEventResult.ignored;
|
||||
},
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
||||
@ -137,6 +137,47 @@ void main() {
|
||||
expect(find.text('Suggestions'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Can close search with escape button and return null', (WidgetTester tester) async {
|
||||
final _TestSearchDelegate delegate = _TestSearchDelegate();
|
||||
addTearDown(() => delegate.dispose());
|
||||
final List<String?> selectedResults = <String?>[];
|
||||
|
||||
await tester.pumpWidget(TestHomePage(delegate: delegate, results: selectedResults));
|
||||
|
||||
// We are on the homepage.
|
||||
expect(find.text('HomeBody'), findsOneWidget);
|
||||
expect(find.text('HomeTitle'), findsOneWidget);
|
||||
expect(find.text('Suggestions'), findsNothing);
|
||||
|
||||
// Open search.
|
||||
await tester.tap(find.byTooltip('Search'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('HomeBody'), findsNothing);
|
||||
expect(find.text('HomeTitle'), findsNothing);
|
||||
expect(find.text('Suggestions'), findsOneWidget);
|
||||
expect(find.text('Bottom'), findsOneWidget);
|
||||
|
||||
// Simulate escape button.
|
||||
await simulateKeyDownEvent(LogicalKeyboardKey.escape, platform: 'windows');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(selectedResults, <String?>[null]);
|
||||
|
||||
// We are on the homepage again.
|
||||
expect(find.text('HomeBody'), findsOneWidget);
|
||||
expect(find.text('HomeTitle'), findsOneWidget);
|
||||
expect(find.text('Suggestions'), findsNothing);
|
||||
|
||||
// Open search again.
|
||||
await tester.tap(find.byTooltip('Search'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('HomeBody'), findsNothing);
|
||||
expect(find.text('HomeTitle'), findsNothing);
|
||||
expect(find.text('Suggestions'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Hint text color overridden', (WidgetTester tester) async {
|
||||
const String searchHintText = 'Enter search terms';
|
||||
final _TestSearchDelegate delegate = _TestSearchDelegate(searchHint: searchHintText);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user