Use CollectionInfo and CollectionItemInfo api in RadioGroup and
RadioButton Allow RadioGroups to be recognized as groups of objects by accessibility services. This lays a foundation to better describe these groups by exposing the number of buttons and the position of each. Bug: 144591511 Test: Tested on various app permission fragments in Settings and in the time picker in Clock. Added cts tests. Change-Id: Ie0c41d8c9b131ca29bba5387171a85dfdbb8db7e
This commit is contained in:
@@ -18,6 +18,7 @@ package android.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,19 +39,19 @@ import android.util.AttributeSet;
|
||||
* guide.</p>
|
||||
*
|
||||
* <p><strong>XML attributes</strong></p>
|
||||
* <p>
|
||||
* See {@link android.R.styleable#CompoundButton CompoundButton Attributes},
|
||||
* {@link android.R.styleable#Button Button Attributes},
|
||||
* {@link android.R.styleable#TextView TextView Attributes},
|
||||
* <p>
|
||||
* See {@link android.R.styleable#CompoundButton CompoundButton Attributes},
|
||||
* {@link android.R.styleable#Button Button Attributes},
|
||||
* {@link android.R.styleable#TextView TextView Attributes},
|
||||
* {@link android.R.styleable#View View Attributes}
|
||||
* </p>
|
||||
*/
|
||||
public class RadioButton extends CompoundButton {
|
||||
|
||||
|
||||
public RadioButton(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
|
||||
public RadioButton(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, com.android.internal.R.attr.radioButtonStyle);
|
||||
}
|
||||
@@ -81,4 +82,20 @@ public class RadioButton extends CompoundButton {
|
||||
public CharSequence getAccessibilityClassName() {
|
||||
return RadioButton.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
if (getParent() instanceof RadioGroup) {
|
||||
RadioGroup radioGroup = (RadioGroup) getParent();
|
||||
if (radioGroup.getOrientation() == LinearLayout.HORIZONTAL) {
|
||||
info.setCollectionItemInfo(AccessibilityNodeInfo.CollectionItemInfo.obtain(0, 1,
|
||||
radioGroup.getIndexWithinVisibleButtons(this), 1, false, isChecked()));
|
||||
} else {
|
||||
info.setCollectionItemInfo(AccessibilityNodeInfo.CollectionItemInfo.obtain(
|
||||
radioGroup.getIndexWithinVisibleButtons(this), 1, 0, 1,
|
||||
false, isChecked()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.widget;
|
||||
|
||||
import android.annotation.IdRes;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -26,6 +27,7 @@ import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStructure;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.autofill.AutofillManager;
|
||||
import android.view.autofill.AutofillValue;
|
||||
|
||||
@@ -93,6 +95,7 @@ public class RadioGroup extends LinearLayout {
|
||||
if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) {
|
||||
setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
|
||||
}
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
|
||||
// retrieve selected radio button as requested by the user in the
|
||||
// XML layout file
|
||||
@@ -475,4 +478,50 @@ public class RadioGroup extends LinearLayout {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
if (this.getOrientation() == HORIZONTAL) {
|
||||
info.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(1,
|
||||
getVisibleChildCount(), false,
|
||||
AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_SINGLE));
|
||||
} else {
|
||||
info.setCollectionInfo(
|
||||
AccessibilityNodeInfo.CollectionInfo.obtain(getVisibleChildCount(),
|
||||
1, false,
|
||||
AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_SINGLE));
|
||||
}
|
||||
}
|
||||
|
||||
private int getVisibleChildCount() {
|
||||
int count = 0;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
if (this.getChildAt(i) instanceof RadioButton) {
|
||||
if (((RadioButton) this.getChildAt(i)).getVisibility() == VISIBLE) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int getIndexWithinVisibleButtons(@Nullable View child) {
|
||||
if (!(child instanceof RadioButton)) {
|
||||
return -1;
|
||||
}
|
||||
int index = 0;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
if (this.getChildAt(i) instanceof RadioButton) {
|
||||
RadioButton radioButton = (RadioButton) this.getChildAt(i);
|
||||
if (radioButton == child) {
|
||||
return index;
|
||||
}
|
||||
if (radioButton.getVisibility() == VISIBLE) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user