Unverified Commit 06140f2b authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Closing search with system back button works (#18174)

Fixes #18145.
parent 0a26ac09
......@@ -26,8 +26,9 @@ import 'theme.dart';
/// to the empty string. When `query` is set to null, `delegate.query` will
/// be used as the initial query.
///
/// The method returns the selected search result, which can be set in the
/// [SearchDelegate.close] call.
/// This method returns the selected search result, which can be set in the
/// [SearchDelegate.close] call. If the search page is closed with the system
/// back button, it returns null.
///
/// A given [SearchDelegate] can only be associated with one active [showSearch]
/// call. Call [SearchDelegate.close] before re-using the same delegate instance
......@@ -52,14 +53,11 @@ Future<T> showSearch<T>({
}) {
assert(delegate != null);
assert(context != null);
assert(delegate._result == null || delegate._result.isCompleted);
delegate._result = new Completer<T>();
delegate.query = query ?? delegate.query;
delegate._currentBody = _SearchBody.suggestions;
Navigator.of(context).push(new _SearchPageRoute<T>(
return Navigator.of(context).push(new _SearchPageRoute<T>(
delegate: delegate,
));
return delegate._result.future;
}
/// Delegate for [showSearch] to define the content of the search page.
......@@ -215,7 +213,6 @@ abstract class SearchDelegate<T> {
void close(BuildContext context, T result) {
_currentBody = null;
_focusNode.unfocus();
_result.complete(result);
Navigator.of(context)
..popUntil((Route<dynamic> route) => route == _route)
..pop(result);
......@@ -242,8 +239,6 @@ abstract class SearchDelegate<T> {
_currentBodyNotifier.value = value;
}
Completer<T> _result;
_SearchPageRoute<T> _route;
}
......@@ -263,7 +258,7 @@ enum _SearchBody {
}
class _SearchPageRoute<T> extends PageRoute<void> {
class _SearchPageRoute<T> extends PageRoute<T> {
_SearchPageRoute({
@required this.delegate,
}) : assert(delegate != null) {
......@@ -323,10 +318,11 @@ class _SearchPageRoute<T> extends PageRoute<void> {
}
@override
void didComplete(void result) {
void didComplete(T result) {
super.didComplete(result);
assert(delegate._route == this);
delegate._route = null;
delegate._currentBody = null;
}
}
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
......@@ -42,6 +43,51 @@ void main() {
expect(selectedResults, <String>['Result']);
});
testWidgets('Can close search with system back button to return null', (WidgetTester tester) async {
// regression test for https://github.com/flutter/flutter/issues/18145
final _TestSearchDelegate delegate = new _TestSearchDelegate();
final List<String> selectedResults = <String>[];
await tester.pumpWidget(new 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);
// Simulate system back button
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
await BinaryMessages.handlePlatformMessage('flutter/navigation', message, (_) {});
await tester.pumpAndSettle();
expect(selectedResults, <void>[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('Requests suggestions', (WidgetTester tester) async {
final _TestSearchDelegate delegate = new _TestSearchDelegate();
......@@ -414,7 +460,7 @@ void main() {
expect(find.text('HomeBody'), findsOneWidget);
expect(find.text('Suggestions'), findsNothing);
expect(find.text('Nested Suggestions'), findsNothing);
expect(nestedSearchResults, hasLength(0));
expect(nestedSearchResults, <String>[null]);
expect(selectedResults, <String>['Result Foo']);
});
}
......
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