fix: add parameter to maintainState of SearchDelegate (#152444)
Add parameter to `showSearch`, which is passed to `_SearchPageRoute` to maintain the state of the SearchDelegate. - fix #43582 _Just contributed this change to start the conversation on how the #43582 can be addressed. Have not added tests yet._
This commit is contained in:
parent
a9b2d8d6d4
commit
6f98b485ec
@ -48,6 +48,10 @@ import 'theme.dart';
|
||||
/// route created by this method is pushed to the nearest navigator to the
|
||||
/// given `context`. It can not be `null`.
|
||||
///
|
||||
/// The `maintainState` argument is used to determine if the route should remain
|
||||
/// in memory when it is inactive (see [ModalRoute.maintainState] for more details].
|
||||
/// By default, `maintainState` is `false`.
|
||||
///
|
||||
/// The transition to the search page triggered by this method looks best if the
|
||||
/// screen triggering the transition contains an [AppBar] at the top and the
|
||||
/// transition is called from an [IconButton] that's part of [AppBar.actions].
|
||||
@ -68,11 +72,13 @@ Future<T?> showSearch<T>({
|
||||
required SearchDelegate<T> delegate,
|
||||
String? query = '',
|
||||
bool useRootNavigator = false,
|
||||
bool maintainState = false,
|
||||
}) {
|
||||
delegate.query = query ?? delegate.query;
|
||||
delegate._currentBody = _SearchBody.suggestions;
|
||||
return Navigator.of(context, rootNavigator: useRootNavigator).push(_SearchPageRoute<T>(
|
||||
delegate: delegate,
|
||||
maintainState: maintainState
|
||||
));
|
||||
}
|
||||
|
||||
@ -417,6 +423,7 @@ enum _SearchBody {
|
||||
class _SearchPageRoute<T> extends PageRoute<T> {
|
||||
_SearchPageRoute({
|
||||
required this.delegate,
|
||||
required this.maintainState,
|
||||
}) {
|
||||
assert(
|
||||
delegate._route == null,
|
||||
@ -429,6 +436,9 @@ class _SearchPageRoute<T> extends PageRoute<T> {
|
||||
|
||||
final SearchDelegate<T> delegate;
|
||||
|
||||
@override
|
||||
final bool maintainState;
|
||||
|
||||
@override
|
||||
Color? get barrierColor => null;
|
||||
|
||||
@ -438,9 +448,6 @@ class _SearchPageRoute<T> extends PageRoute<T> {
|
||||
@override
|
||||
Duration get transitionDuration => const Duration(milliseconds: 300);
|
||||
|
||||
@override
|
||||
bool get maintainState => false;
|
||||
|
||||
@override
|
||||
Widget buildTransitions(
|
||||
BuildContext context,
|
||||
|
@ -1175,6 +1175,63 @@ void main() {
|
||||
await tester.pump();
|
||||
expect(textField.controller!.text.length, 15);
|
||||
}, skip: kIsWeb); // [intended] We do not use Flutter-rendered context menu on the Web.
|
||||
|
||||
testWidgets('showSearch with maintainState on the route', (WidgetTester tester) async {
|
||||
final _MyNavigatorObserver navigationObserver = _MyNavigatorObserver();
|
||||
|
||||
final _TestEmptySearchDelegate delegate = _TestEmptySearchDelegate();
|
||||
addTearDown(delegate.dispose);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
navigatorObservers: <NavigatorObserver>[navigationObserver],
|
||||
home: Builder(builder: (BuildContext context) => Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await showSearch(
|
||||
context: context,
|
||||
delegate: delegate,
|
||||
);
|
||||
},
|
||||
child: const Text('showSearch'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await showSearch(
|
||||
context: context,
|
||||
delegate: delegate,
|
||||
maintainState: true,
|
||||
);
|
||||
},
|
||||
child: const Text('showSearchWithMaintainState'),
|
||||
),
|
||||
],
|
||||
)),
|
||||
));
|
||||
|
||||
expect(navigationObserver.pushCount, 0);
|
||||
expect(navigationObserver.maintainState, false);
|
||||
|
||||
// showSearch normal and back.
|
||||
await tester.tap(find.text('showSearch'));
|
||||
await tester.pumpAndSettle();
|
||||
final Finder backButtonFinder = find.byType(BackButton);
|
||||
expect(backButtonFinder, findsWidgets);
|
||||
await tester.tap(find.byTooltip('Close'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(navigationObserver.pushCount, 1);
|
||||
expect(navigationObserver.maintainState, false);
|
||||
|
||||
// showSearch with maintainState.
|
||||
await tester.tap(find.text('showSearchWithMaintainState'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(backButtonFinder, findsWidgets);
|
||||
await tester.tap(find.byTooltip('Close'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(navigationObserver.pushCount, 2);
|
||||
expect(navigationObserver.maintainState, true);
|
||||
});
|
||||
}
|
||||
|
||||
class TestHomePage extends StatelessWidget {
|
||||
@ -1358,6 +1415,7 @@ class _TestEmptySearchDelegate extends SearchDelegate<String> {
|
||||
}
|
||||
|
||||
class _MyNavigatorObserver extends NavigatorObserver {
|
||||
bool maintainState = false;
|
||||
int pushCount = 0;
|
||||
|
||||
@override
|
||||
@ -1366,6 +1424,9 @@ class _MyNavigatorObserver extends NavigatorObserver {
|
||||
if (<String>['nested', '/'].contains(route.settings.name)) {
|
||||
return;
|
||||
}
|
||||
if (route is PageRoute) {
|
||||
maintainState = route.maintainState;
|
||||
}
|
||||
pushCount++;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user