android - 当可访问性打开时,如何更改/覆盖复选框内容描述值?
问题描述
我的活动中有一个复选框并提供了android:contentDescription="selected"
. 同样在如下提供的java类中。
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
checkbox.setContentDescription(b ? "Selected" : "Not Selected");
}
});
当我打开对讲并选中复选框时,它会显示“已选中/未选中”而不是“已选中/未选中”。
它采用 OS 的默认值(因不同制造商和 OS 版本而异),但未提供值。有什么办法,我们可以解决这个问题吗?
解决方案
所以我不久前遇到了这个问题,发现了一个相当老套的解决方法。像这样创建和使用 CheckBox 的子类并替换字符串:
public class CustomCheckBox extends CheckBox {
// constructors...
@Override
public CharSequence getAccessibilityClassName() {
// override to disable the "checkbox" readout
return CustomCheckBox.class.getSimpleName();
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
// by setting checkable to false the default checked/unchecked readouts are disabled
info.setCheckable(false);
// ...and then you can set whatever you want as a text
info.setText(getStateDescription());
}
@Override
public void setChecked(boolean checked) {
if (checked == isChecked()) return;
super.setChecked(checked);
// since we've disabled the checked/unchecked readouts
// we are forced to manually announce changes to the state
announceForAccessibility(getStateDescription());
}
private String getStateDescription() {
if (isChecked()) {
return "Custom checked description";
} else {
return "Custom unchecked description";
}
}
}
另外,我应该先说我没有尝试过下面提到的东西,但似乎 Android R (API 30) 通过添加setStateDescription(CharSequence)
到CompoundButton
Source Doc添加了一种官方方法来覆盖它
/**
* This function is called when an instance or subclass sets the state description. Once this
* is called and the argument is not null, the app developer will be responsible for updating
* state description when checked state changes and we will not set state description
* in {@link #setChecked}. App developers can restore the default behavior by setting the
* argument to null. If {@link #setChecked} is called first and then setStateDescription is
* called, two state change events will be merged by event throttling and we can still get
* the correct state description.
*
* @param stateDescription The state description.
*/
@Override
public void setStateDescription(@Nullable CharSequence stateDescription) {
mCustomStateDescription = stateDescription;
if (stateDescription == null) {
setDefaultStateDescritption();
} else {
super.setStateDescription(stateDescription);
}
}
推荐阅读
- git - Git Braching/Merging 策略:release + hotfix 分支,master 的意义何在
- python - Python / PyQt4 内存泄漏
- php - PHP 使用变量构建数组
- android - com.android.builder.dexing.DexArchiveBuilderException
- rust - 为什么这个值的寿命不够长?
- c# - UWP - 获取 Gridview 的第一个孩子
- .net - 应该只从主 .NET UI 线程调用 SaveSetting 和 GetSetting 吗?
- asp.net-mvc - @Html.EditorFor(model => model.Username) 不显示文本框
- java - 使用 AsyncHTTPConduit CXF (JAVA) 的非阻塞 Web 服务客户端
- php - PHP超时执行多个curl和filegets