diff --git a/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/shell/platform/android/io/flutter/view/AccessibilityBridge.java index ba0d90455990c..72b78221dd625 100644 --- a/shell/platform/android/io/flutter/view/AccessibilityBridge.java +++ b/shell/platform/android/io/flutter/view/AccessibilityBridge.java @@ -885,7 +885,8 @@ && shouldSetCollectionInfo(semanticsNode)) { // Scopes routes are not focusable, only need to set the content // for non-scopes-routes semantics nodes. if (semanticsNode.hasFlag(Flag.IS_TEXT_FIELD)) { - result.setText(semanticsNode.getValueLabelHint()); + result.setText(semanticsNode.getValue()); + result.setHintText(semanticsNode.getTextFieldHint()); } else if (!semanticsNode.hasFlag(Flag.SCOPES_ROUTE)) { CharSequence content = semanticsNode.getValueLabelHint(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { @@ -2773,18 +2774,47 @@ private float max(float a, float b, float c, float d) { return Math.max(a, Math.max(b, Math.max(c, d))); } - private CharSequence getValueLabelHint() { - CharSequence[] array; + private CharSequence getValue() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return value; + } else { + return createSpannableString(value, valueAttributes); + } + } + + private CharSequence getLabel() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return label; + } else { + return createSpannableString(label, labelAttributes); + } + } + + private CharSequence getHint() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - array = new CharSequence[] {value, label, hint}; + return hint; } else { - array = - new CharSequence[] { - createSpannableString(value, valueAttributes), - createSpannableString(label, labelAttributes), - createSpannableString(hint, hintAttributes), - }; + return createSpannableString(hint, hintAttributes); } + } + + private CharSequence getValueLabelHint() { + CharSequence[] array = new CharSequence[] {getValue(), getLabel(), getHint()}; + CharSequence result = null; + for (CharSequence word : array) { + if (word != null && word.length() > 0) { + if (result == null || result.length() == 0) { + result = word; + } else { + result = TextUtils.concat(result, ", ", word); + } + } + } + return result; + } + + private CharSequence getTextFieldHint() { + CharSequence[] array = new CharSequence[] {getLabel(), getHint()}; CharSequence result = null; for (CharSequence word : array) { if (word != null && word.length() > 0) { diff --git a/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java b/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java index a88c0323a7b33..0d4a46b10088c 100644 --- a/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java +++ b/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java @@ -77,11 +77,13 @@ public void itDescribesNonTextFieldsWithAContentDescription() { } @Test - public void itDescribesTextFieldsWithText() { + public void itDescribesTextFieldsWithTextAndHint() { AccessibilityBridge accessibilityBridge = setUpBridge(); TestSemanticsNode testSemanticsNode = new TestSemanticsNode(); - testSemanticsNode.label = "Hello, World"; + testSemanticsNode.value = "Hello, World"; + testSemanticsNode.label = "some label"; + testSemanticsNode.hint = "some hint"; testSemanticsNode.addFlag(AccessibilityBridge.Flag.IS_TEXT_FIELD); TestSemanticsUpdate testSemanticsUpdate = testSemanticsNode.toUpdate(); testSemanticsUpdate.sendUpdateToBridge(accessibilityBridge); @@ -89,6 +91,7 @@ public void itDescribesTextFieldsWithText() { assertEquals(nodeInfo.getContentDescription(), null); assertEquals(nodeInfo.getText().toString(), "Hello, World"); + assertEquals(nodeInfo.getHintText().toString(), "some label, some hint"); } @Test