mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Hint text semantics to be excluded in a11y read out if hintText is not visible. (#119198)
* Update input_decorator.dart * Update text_field_test.dart * Update time_picker.dart Update time_picker.dart
This commit is contained in:
parent
6c12e39947
commit
b227df3089
@ -2193,7 +2193,6 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
|
||||
opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0,
|
||||
duration: _kTransitionDuration,
|
||||
curve: _kTransitionCurve,
|
||||
alwaysIncludeSemantics: isEmpty || (decoration.labelText == null && decoration.label == null),
|
||||
child: Text(
|
||||
hintText,
|
||||
style: hintStyle,
|
||||
|
||||
@ -2050,12 +2050,9 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
|
||||
|
||||
final InputDecorationTheme inputDecorationTheme = timePickerTheme.inputDecorationTheme ?? defaultTheme.inputDecorationTheme;
|
||||
InputDecoration inputDecoration = const InputDecoration().applyDefaults(inputDecorationTheme);
|
||||
// If screen reader is in use, make the hint text say hours/minutes.
|
||||
// Otherwise, remove the hint text when focused because the centered cursor
|
||||
// Remove the hint text when focused because the centered cursor
|
||||
// appears odd above the hint text.
|
||||
final String? hintText = MediaQuery.accessibleNavigationOf(context) || View.of(context).platformDispatcher.semanticsEnabled
|
||||
? widget.semanticHintText
|
||||
: (focusNode.hasFocus ? null : _formattedValue);
|
||||
final String? hintText = focusNode.hasFocus ? null : _formattedValue;
|
||||
|
||||
// Because the fill color is specified in both the inputDecorationTheme and
|
||||
// the TimePickerTheme, if there's one in the user's input decoration theme,
|
||||
@ -2102,26 +2099,29 @@ class _HourMinuteTextFieldState extends State<_HourMinuteTextField> with Restora
|
||||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1),
|
||||
child: UnmanagedRestorationScope(
|
||||
bucket: bucket,
|
||||
child: TextFormField(
|
||||
restorationId: 'hour_minute_text_form_field',
|
||||
autofocus: widget.autofocus ?? false,
|
||||
expands: true,
|
||||
maxLines: null,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
LengthLimitingTextInputFormatter(2),
|
||||
],
|
||||
focusNode: focusNode,
|
||||
textAlign: TextAlign.center,
|
||||
textInputAction: widget.inputAction,
|
||||
keyboardType: TextInputType.number,
|
||||
style: effectiveStyle,
|
||||
controller: controller.value,
|
||||
decoration: inputDecoration,
|
||||
validator: widget.validator,
|
||||
onEditingComplete: () => widget.onSavedSubmitted(controller.value.text),
|
||||
onSaved: widget.onSavedSubmitted,
|
||||
onFieldSubmitted: widget.onSavedSubmitted,
|
||||
onChanged: widget.onChanged,
|
||||
child: Semantics(
|
||||
label: widget.semanticHintText,
|
||||
child: TextFormField(
|
||||
restorationId: 'hour_minute_text_form_field',
|
||||
autofocus: widget.autofocus ?? false,
|
||||
expands: true,
|
||||
maxLines: null,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
LengthLimitingTextInputFormatter(2),
|
||||
],
|
||||
focusNode: focusNode,
|
||||
textAlign: TextAlign.center,
|
||||
textInputAction: widget.inputAction,
|
||||
keyboardType: TextInputType.number,
|
||||
style: effectiveStyle,
|
||||
controller: controller.value,
|
||||
decoration: inputDecoration,
|
||||
validator: widget.validator,
|
||||
onEditingComplete: () => widget.onSavedSubmitted(controller.value.text),
|
||||
onSaved: widget.onSavedSubmitted,
|
||||
onFieldSubmitted: widget.onSavedSubmitted,
|
||||
onChanged: widget.onChanged,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -6862,7 +6862,7 @@ void main() {
|
||||
await tester.tap(find.byKey(key));
|
||||
await tester.pump();
|
||||
|
||||
expect(node.label, 'label\nhint');
|
||||
expect(node.label, 'label');
|
||||
expect(node.value, '');
|
||||
semantics.dispose();
|
||||
});
|
||||
@ -6930,7 +6930,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('TextField semantics always include hint when no label is given', (WidgetTester tester) async {
|
||||
testWidgets('TextField semantics only include hint when it is visible', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
final TextEditingController controller = TextEditingController(text: 'value');
|
||||
final Key key = UniqueKey();
|
||||
@ -6949,15 +6949,23 @@ void main() {
|
||||
|
||||
final SemanticsNode node = tester.getSemantics(find.byKey(key));
|
||||
|
||||
expect(node.label, 'hint');
|
||||
expect(node.label, '');
|
||||
expect(node.value, 'value');
|
||||
|
||||
// Focus text field.
|
||||
await tester.tap(find.byKey(key));
|
||||
await tester.pump();
|
||||
|
||||
expect(node.label, 'hint');
|
||||
expect(node.label, '');
|
||||
expect(node.value, 'value');
|
||||
|
||||
// Clear the Text.
|
||||
await tester.enterText(find.byType(TextField), '');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(node.value, '');
|
||||
expect(node.label, 'hint');
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
@ -7698,7 +7706,7 @@ void main() {
|
||||
expect(semantics, hasSemantics(TestSemantics.root(
|
||||
children: <TestSemantics>[
|
||||
TestSemantics.rootChild(
|
||||
label: 'label\nhint',
|
||||
label: 'label',
|
||||
id: 1,
|
||||
textDirection: TextDirection.ltr,
|
||||
textSelection: const TextSelection(baseOffset: 0, extentOffset: 0),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user