问题

咱们一般给一个控件设置描绘时,会这样:

xxxView.setContentDescription("xxx");

可是,当你给EditText设置这个时,会发现毫无卵用。为什么呢?

搜了下EditText和其直接父类TextView,没有重写setContentDescription办法,那应该不是setXXX时发生改动,而是getXXX的问题。

公然,在TextView中发现:

/**
* Returns the text that should be exposed to accessibility services.
* <papproach>
* This approximAPPates what is displayed visually. If the user has源码 specified
* that acceappstoressibility services sh源码ould sp源码编辑器编程猫下载eak passwords, this method will
* bypass any password transformation m源码网ethod and ret源码urn unobscured tex源码网t.
*
* @return the text that should be exposed to accessibility services, may
*         be {@code nappearanceull} if no tapproachext is set
*/
@Nullable
@UnsupportedAppUsage
private CharSequence getTextForAccessibility() {
// If the te源码集市xt is empty, we must be showing t源码编程he hint text.
if (TextUappletils.isEmptappeary(mText)) {
return mHint;
}
// Otherwise, return whatever text is being displayed.
return TextUtils.trimToParcelableSize(mTransformed);
}

所以EapplicationditText在获取到无障碍焦点时,只会朗诵hint文本,而不是contentDescription。其实这个规划是没有问题的,可修正控件,在没有输入内容时,就应该朗诵hint源码共享网

可是,某些自定义控件是长这样的:

自定义EditText的无障碍描绘(不读hint)

label是自appear定义View画上去的,没做特别apple处理的情况下Talkback辨认不到,最好的体验是把左边的label也跟着读出来(比方读成:“列车车次,例:G1”),这可咋办?

处理

很显然,不能直接去改hint,否则UI显现不对。

查验一:获取焦点时我自己读一串文本行不行

咱们知道,能够经过appointment

xxxView.announceForAccessibility("xxx");源码编辑器

来进行无障碍朗诵,可是并没有一个相似setOnFocusChangeList源码编辑器手机版下载enappreciateer的办法来专门监听无障碍焦点,所以这个欠好搞。

查验二:Read the fucking code

其实无障碍开发中还有一些要害办法,且Talkback这些无appearance障碍辅助工具究竟其实也会触发这些办法的:

xxxView.requestAcce源码集市ssibilityFocus(); // 获取无障碍焦点,主动朗诵已设置的描绘
xxxVieapprovew.sendAccessibilityEvent(AccessapproachibilityEvent.TYPE_VIEW_appointmentACCESSIBILITY_FOCUSED); // 效果和前者差不多,且前者究竟也要调用此办法

深化后能够跟踪到:

p源码编辑器手机版下载ublic void sendAccessibilityEventUncheckedInternal(AccessibiliAPPtyEvent event) {
...
onInitializeAcce源码编辑器编程猫下载ssibilityEvent(event);
// Only a subset of accessibility events populates text content.
if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0)源码编辑器手机版下载 {
dis源码年代pa源码年代tchPopulateAccessibilityEvent(event);
}
// In the beginning we called #isShowapproven(), so we know that getParent() is not null.
ViewParent parent = getParent();
if (parent != null) {
getParent().requestSendAccessibilityEvent(this, event);
}
}

这个onInitializeAccessibilityEvent的源码注释写得很了解,便是控件获取到无app装置下载障碍作业时会触发,但经过event参数咱们形似做不了什么。

在Textview中咱们发现,与onInitializeAccessibilityEventInternal相邻有一个内部方appearonInitializeAccessibilityNodeInfoInternal

public void onInitializeAccessibilityNodeInfo源码编辑器编程猫下载Intapproachernal(AccessibilityNodeInfo info) {
super.onInitializeAccessibilitapproveyNo源码年代deInfoInteapprovernal(info);
final bapp装置下载oolean源码网 isPassword = hasPasswordTransfo源码编辑器编程猫下载rmationMethod();
info.setPassword(isPassword);
info.setText(源码编辑器getTextForAccessibility());
info.setHintText(mHint);
info.setShow源码网ingHintText(isShowingHint());
...
}

这个 info.setText(getTextForAccessibility()); 便是要害了,它其实才是究竟朗诵出来的那个文本。

公共办法onInitializeAccesappointmentsibilityNodeInfo的注释也说清楚:Initializes an {@link AccessibilityNodeInfo}源码网站 with information abou源码共享网t this viappearew. 此办法初始化一些View的无障碍基本信息。

究竟处理:

在自定义的EditText类中重写办法,掩盖文本appointment,这样在朗诵时便是自己想要的了:

@Override
public void onInitialiappearzeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onIniappeartializeAccappreciateessibilityNodeInfo(info);
// 关于EditText,系apple统无障碍朗诵只读hint,需经过节点info掩盖自定义内容
info源码网站.setText("xxx" + getHint());
}

Tips:其实这儿为了API统一,我是直接 info.setText(getContentDescription()); 便利许多。