Add route/routeName to search page (#20190)
This commit is contained in:
parent
d1f446e559
commit
a0b5448b84
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import 'app_bar.dart';
|
import 'app_bar.dart';
|
||||||
@ -389,6 +390,7 @@ class _SearchPageState<T> extends State<_SearchPage<T>> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ThemeData theme = widget.delegate.appBarTheme(context);
|
final ThemeData theme = widget.delegate.appBarTheme(context);
|
||||||
|
final String searchFieldLabel = MaterialLocalizations.of(context).searchFieldLabel;
|
||||||
Widget body;
|
Widget body;
|
||||||
switch(widget.delegate._currentBody) {
|
switch(widget.delegate._currentBody) {
|
||||||
case _SearchBody.suggestions:
|
case _SearchBody.suggestions:
|
||||||
@ -404,32 +406,47 @@ class _SearchPageState<T> extends State<_SearchPage<T>> {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
String routeName;
|
||||||
|
switch (defaultTargetPlatform) {
|
||||||
|
case TargetPlatform.iOS:
|
||||||
|
routeName = '';
|
||||||
|
break;
|
||||||
|
case TargetPlatform.android:
|
||||||
|
case TargetPlatform.fuchsia:
|
||||||
|
routeName = searchFieldLabel;
|
||||||
|
}
|
||||||
|
|
||||||
return new Scaffold(
|
return new Semantics(
|
||||||
appBar: new AppBar(
|
explicitChildNodes: true,
|
||||||
backgroundColor: theme.primaryColor,
|
scopesRoute: true,
|
||||||
iconTheme: theme.primaryIconTheme,
|
namesRoute: true,
|
||||||
textTheme: theme.primaryTextTheme,
|
label: routeName,
|
||||||
brightness: theme.primaryColorBrightness,
|
child: new Scaffold(
|
||||||
leading: widget.delegate.buildLeading(context),
|
appBar: new AppBar(
|
||||||
title: new TextField(
|
backgroundColor: theme.primaryColor,
|
||||||
controller: queryTextController,
|
iconTheme: theme.primaryIconTheme,
|
||||||
focusNode: widget.delegate._focusNode,
|
textTheme: theme.primaryTextTheme,
|
||||||
style: theme.textTheme.title,
|
brightness: theme.primaryColorBrightness,
|
||||||
textInputAction: TextInputAction.search,
|
leading: widget.delegate.buildLeading(context),
|
||||||
onSubmitted: (String _) {
|
title: new TextField(
|
||||||
widget.delegate.showResults(context);
|
controller: queryTextController,
|
||||||
},
|
focusNode: widget.delegate._focusNode,
|
||||||
decoration: new InputDecoration(
|
style: theme.textTheme.title,
|
||||||
border: InputBorder.none,
|
textInputAction: TextInputAction.search,
|
||||||
hintText: MaterialLocalizations.of(context).searchFieldLabel,
|
onSubmitted: (String _) {
|
||||||
|
widget.delegate.showResults(context);
|
||||||
|
},
|
||||||
|
decoration: new InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: searchFieldLabel,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
actions: widget.delegate.buildActions(context),
|
||||||
|
),
|
||||||
|
body: new AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
child: body,
|
||||||
),
|
),
|
||||||
actions: widget.delegate.buildActions(context),
|
|
||||||
),
|
|
||||||
body: new AnimatedSwitcher(
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
child: body,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../widgets/semantics_tester.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Can open and close search', (WidgetTester tester) async {
|
testWidgets('Can open and close search', (WidgetTester tester) async {
|
||||||
final _TestSearchDelegate delegate = new _TestSearchDelegate();
|
final _TestSearchDelegate delegate = new _TestSearchDelegate();
|
||||||
@ -477,6 +480,109 @@ void main() {
|
|||||||
|
|
||||||
expect(tester.testTextInput.setClientArgs['inputAction'], TextInputAction.search.toString());
|
expect(tester.testTextInput.setClientArgs['inputAction'], TextInputAction.search.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('contributes semantics', () {
|
||||||
|
TestSemantics buildExpected({String routeName}) {
|
||||||
|
return new TestSemantics.root(
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics(
|
||||||
|
id: 1,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics(
|
||||||
|
id: 7,
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.scopesRoute,
|
||||||
|
SemanticsFlag.namesRoute,
|
||||||
|
],
|
||||||
|
label: routeName,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics(
|
||||||
|
id: 8,
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isButton,
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isEnabled,
|
||||||
|
],
|
||||||
|
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||||
|
label: 'Suggestions',
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
),
|
||||||
|
new TestSemantics(
|
||||||
|
id: 9,
|
||||||
|
children: <TestSemantics>[
|
||||||
|
new TestSemantics(
|
||||||
|
id: 10,
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isButton,
|
||||||
|
SemanticsFlag.hasEnabledState,
|
||||||
|
SemanticsFlag.isEnabled,
|
||||||
|
],
|
||||||
|
actions: <SemanticsAction>[SemanticsAction.tap],
|
||||||
|
label: 'Back',
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
),
|
||||||
|
new TestSemantics(
|
||||||
|
id: 11,
|
||||||
|
flags: <SemanticsFlag>[
|
||||||
|
SemanticsFlag.isTextField,
|
||||||
|
SemanticsFlag.isFocused,
|
||||||
|
SemanticsFlag.isHeader,
|
||||||
|
SemanticsFlag.namesRoute,
|
||||||
|
],
|
||||||
|
actions: <SemanticsAction>[
|
||||||
|
SemanticsAction.tap,
|
||||||
|
SemanticsAction.setSelection,
|
||||||
|
SemanticsAction.paste,
|
||||||
|
],
|
||||||
|
label: 'Search',
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
testWidgets('includes routeName on Android', (WidgetTester tester) async {
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
final _TestSearchDelegate delegate = new _TestSearchDelegate();
|
||||||
|
await tester.pumpWidget(new TestHomePage(
|
||||||
|
delegate: delegate,
|
||||||
|
));
|
||||||
|
|
||||||
|
await tester.tap(find.byTooltip('Search'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(buildExpected(routeName: 'Search'),
|
||||||
|
ignoreId: true, ignoreRect: true, ignoreTransform: true));
|
||||||
|
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('does not include routeName on iOS', (WidgetTester tester) async {
|
||||||
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
||||||
|
final SemanticsTester semantics = new SemanticsTester(tester);
|
||||||
|
final _TestSearchDelegate delegate = new _TestSearchDelegate();
|
||||||
|
await tester.pumpWidget(new TestHomePage(
|
||||||
|
delegate: delegate,
|
||||||
|
));
|
||||||
|
|
||||||
|
await tester.tap(find.byTooltip('Search'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(semantics, hasSemantics(buildExpected(routeName: ''),
|
||||||
|
ignoreId: true, ignoreRect: true, ignoreTransform: true));
|
||||||
|
|
||||||
|
debugDefaultTargetPlatformOverride = null;
|
||||||
|
semantics.dispose();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestHomePage extends StatelessWidget {
|
class TestHomePage extends StatelessWidget {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user