>我的布局中有以下一段代码
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/tilPassword"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tilUserName"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/tiePassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:selectAllOnFocus="true"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
在导航到TextInputLayout时,TalkBack宣布:"密码密码编辑框">
所需公告:">密码编辑框">
如果我删除android:hint="Password"
或android:inputType="textPassword"
它按预期工作。
有关设置提示的注意事项
提示应该在 TextInputLayout 上设置,而不是在 TextInputEditText 或 EditText 上设置。如果在 XML 中的子编辑文本上指定了提示,则文本输入布局可能仍能正常工作;TextInputLayout 将使用 EditText 的提示作为其浮动标签。但是,将来修改提示的调用不会更新文本输入布局的提示。为了避免意外行为,请在 TextInputLayout 上调用 setHint(( 和 getHint((,而不是在 EditText 上。
通过检查以下源代码:
文本输入布局类
https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/textfield/TextInputLayout.java
人们可以发现:
文本输入布局辅助功能信息通过以下公共类提供:
public static class AccessibilityDelegate extends AccessibilityDelegateCompat {
private final TextInputLayout layout;
public AccessibilityDelegate(TextInputLayout layout) {
this.layout = layout;
}
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
EditText editText = layout.getEditText();
CharSequence text = (editText != null) ? editText.getText() : null;
CharSequence hintText = layout.getHint();
CharSequence errorText = layout.getError();
CharSequence counterDesc = layout.getCounterOverflowDescription();
boolean showingText = !TextUtils.isEmpty(text);
boolean hasHint = !TextUtils.isEmpty(hintText);
boolean showingError = !TextUtils.isEmpty(errorText);
boolean contentInvalid = showingError || !TextUtils.isEmpty(counterDesc);
if (showingText) {
info.setText(text);
} else if (hasHint) {
info.setText(hintText);
}
if (hasHint) {
info.setHintText(hintText);
info.setShowingHintText(!showingText && hasHint);
}
if (contentInvalid) {
info.setError(showingError ? errorText : counterDesc);
info.setContentInvalid(true);
}
}
}
并且通过调用以下公共方法将其应用于文本输入布局:
public void setTextInputAccessibilityDelegate(TextInputLayout.AccessibilityDelegate delegate) {
if (editText != null) {
ViewCompat.setAccessibilityDelegate(editText, delegate);
}
}
因此,可以扩展:
TextInputLayout.AccessibilityDelegate 类和重写onInitializeAccessibilityNodeInfo(( 只宣布需要的内容。例如,在您的情况下,您可以执行以下操作:
private class CustomTextInputLayoutAccessibilityDelegate extends TextInputLayout.AccessibilityDelegate{
private final TextInputLayout layout;
public CustomTextInputLayoutAccessibilityDelegate(TextInputLayout layout) {
super(layout);
this.layout = layout;
}
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
EditText editText = layout.getEditText();
CharSequence text = (editText != null) ? editText.getText() : null;
CharSequence hintText = layout.getHint();
CharSequence errorText = layout.getError();
//CharSequence counterDesc = layout.getCounterOverflowDescription();
boolean showingText = !TextUtils.isEmpty(text);
boolean hasHint = !TextUtils.isEmpty(hintText);
//boolean showingError = !TextUtils.isEmpty(errorText);
//boolean contentInvalid = showingError || !TextUtils.isEmpty(counterDesc);
if (showingText) {
info.setText(text);
} else if (hasHint) {
info.setText("");
}
if (hasHint) {
info.setHintText("");
info.setShowingHintText(!showingText && hasHint);
}
//if (contentInvalid) {
// info.setError(showingError ? errorText : counterDesc);
// info.setContentInvalid(true);
//}
}
}
然后调用:
tilPassword.setTextInputAccessibilityDelegate(new CustomTextInputLayoutAccessibilityDelegate(tilPassword));
我认为它正在阅读您的TextInputLayout提示。布局不需要提示,将其移动到您的 TextInputEditText。您也可以在布局的顶部布局上使用字段 importantForAccessability="false",如果出于某种原因您需要在那里提示。
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password" />
</android.support.design.widget.TextInputLayout>
它对我有用。在编辑文本提示中使用提示文本。
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/_10"
android:layout_marginLeft="@dimen/_10"
android:layout_marginRight="@dimen/_10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="Address Line 1"/>
</android.support.design.widget.TextInputLayout>
我们可以尝试为 AccessibilityNode 提供自定义角色描述。我们可以检查我们是否使用 info.isPassword 属性显示屏蔽密码。然后相应地构建角色描述。
class MyAccessibilityDelegate(val layout: TextInputLayout) : TextInputLayout.AccessibilityDelegate(layout) {
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
val editText = layout.editText
val content = editText?.text
info.text = content
info.roleDescription = if(!info.isPassword) "password edit text" else "edit text"
info.hintText = ""
info.isShowingHintText = false
editText?.setSelection(content?.length ?: 0)
}
}