Merge "change CompoundButton button to use the accessibility state API"
This commit is contained in:
@@ -80,6 +80,8 @@ public abstract class CompoundButton extends Button implements Checkable {
|
||||
// to sanitize autofill requests.
|
||||
private boolean mCheckedFromResource = false;
|
||||
|
||||
private CharSequence mCustomStateDescription = null;
|
||||
|
||||
private static final int[] CHECKED_STATE_SET = {
|
||||
R.attr.state_checked
|
||||
};
|
||||
@@ -156,6 +158,44 @@ public abstract class CompoundButton extends Button implements Checkable {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@NonNull
|
||||
protected CharSequence getButtonStateDescription() {
|
||||
if (isChecked()) {
|
||||
return getResources().getString(R.string.checked);
|
||||
} else {
|
||||
return getResources().getString(R.string.not_checked);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide **/
|
||||
protected void setDefaultStateDescritption() {
|
||||
if (mCustomStateDescription == null) {
|
||||
super.setStateDescription(getButtonStateDescription());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Changes the checked state of this button.</p>
|
||||
*
|
||||
@@ -167,8 +207,6 @@ public abstract class CompoundButton extends Button implements Checkable {
|
||||
mCheckedFromResource = false;
|
||||
mChecked = checked;
|
||||
refreshDrawableState();
|
||||
notifyViewAccessibilityStateChangedIfNeeded(
|
||||
AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
|
||||
|
||||
// Avoid infinite recursions if setChecked() is called from a listener
|
||||
if (mBroadcasting) {
|
||||
@@ -189,6 +227,8 @@ public abstract class CompoundButton extends Button implements Checkable {
|
||||
|
||||
mBroadcasting = false;
|
||||
}
|
||||
// setStateDescription will not send out event if the description is unchanged.
|
||||
setDefaultStateDescritption();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,7 +52,6 @@ import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewStructure;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.inspector.InspectableProperty;
|
||||
|
||||
import com.android.internal.R;
|
||||
@@ -852,6 +851,9 @@ public class Switch extends CompoundButton {
|
||||
public void setTextOn(CharSequence textOn) {
|
||||
mTextOn = textOn;
|
||||
requestLayout();
|
||||
// Default state is derived from on/off-text, so state has to be updated when on/off-text
|
||||
// are updated.
|
||||
setDefaultStateDescritption();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -872,6 +874,9 @@ public class Switch extends CompoundButton {
|
||||
public void setTextOff(CharSequence textOff) {
|
||||
mTextOff = textOff;
|
||||
requestLayout();
|
||||
// Default state is derived from on/off-text, so state has to be updated when on/off-text
|
||||
// are updated.
|
||||
setDefaultStateDescritption();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1161,6 +1166,17 @@ public class Switch extends CompoundButton {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
|
||||
/** @hide **/
|
||||
@Override
|
||||
@NonNull
|
||||
protected CharSequence getButtonStateDescription() {
|
||||
if (isChecked()) {
|
||||
return mTextOn == null ? getResources().getString(R.string.capital_on) : mTextOn;
|
||||
} else {
|
||||
return mTextOff == null ? getResources().getString(R.string.capital_off) : mTextOff;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
super.setChecked(checked);
|
||||
@@ -1514,23 +1530,6 @@ public class Switch extends CompoundButton {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfoInternal(info);
|
||||
CharSequence switchText = isChecked() ? mTextOn : mTextOff;
|
||||
if (!TextUtils.isEmpty(switchText)) {
|
||||
CharSequence oldText = info.getText();
|
||||
if (TextUtils.isEmpty(oldText)) {
|
||||
info.setText(switchText);
|
||||
} else {
|
||||
StringBuilder newText = new StringBuilder();
|
||||
newText.append(oldText).append(' ').append(switchText);
|
||||
info.setText(newText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final FloatProperty<Switch> THUMB_POS = new FloatProperty<Switch>("thumbPos") {
|
||||
@Override
|
||||
public Float get(Switch object) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.widget;
|
||||
|
||||
import android.annotation.FloatRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -24,6 +25,8 @@ import android.graphics.drawable.LayerDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.inspector.InspectableProperty;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
/**
|
||||
* Displays checked/unchecked states as a button
|
||||
* with a "light" indicator and by default accompanied with the text "ON" or "OFF".
|
||||
@@ -103,6 +106,9 @@ public class ToggleButton extends CompoundButton {
|
||||
*/
|
||||
public void setTextOn(CharSequence textOn) {
|
||||
mTextOn = textOn;
|
||||
// Default state is derived from on/off-text, so state has to be updated when on/off-text
|
||||
// are updated.
|
||||
setDefaultStateDescritption();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,6 +128,9 @@ public class ToggleButton extends CompoundButton {
|
||||
*/
|
||||
public void setTextOff(CharSequence textOff) {
|
||||
mTextOff = textOff;
|
||||
// Default state is derived from on/off-text, so state has to be updated when on/off-text
|
||||
// are updated.
|
||||
setDefaultStateDescritption();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,4 +181,15 @@ public class ToggleButton extends CompoundButton {
|
||||
public CharSequence getAccessibilityClassName() {
|
||||
return ToggleButton.class.getName();
|
||||
}
|
||||
|
||||
/** @hide **/
|
||||
@Override
|
||||
@NonNull
|
||||
protected CharSequence getButtonStateDescription() {
|
||||
if (isChecked()) {
|
||||
return mTextOn == null ? getResources().getString(R.string.capital_on) : mTextOn;
|
||||
} else {
|
||||
return mTextOff == null ? getResources().getString(R.string.capital_off) : mTextOff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3042,6 +3042,11 @@
|
||||
<!-- Default text for a button that can be toggled on and off. -->
|
||||
<string name="capital_off">OFF</string>
|
||||
|
||||
<!-- Default state for CompoundButton for on and off. [CHAR LIMIT=32] -->
|
||||
<string name="checked">checked</string>
|
||||
<!-- Default text for a button that can be toggled on and off. [CHAR LIMIT=32] -->
|
||||
<string name="not_checked">not checked</string>
|
||||
|
||||
<!-- Title of intent resolver dialog when selecting an application to run. -->
|
||||
<string name="whichApplication">Complete action using</string>
|
||||
<!-- Title of intent resolver dialog when selecting an application to run
|
||||
|
||||
@@ -670,14 +670,18 @@
|
||||
<java-symbol type="string" name="capability_desc_canPerformGestures" />
|
||||
<java-symbol type="string" name="capability_title_canPerformGestures" />
|
||||
<java-symbol type="string" name="captive_portal_logged_in_detailed" />
|
||||
<java-symbol type="string" name="capital_off" />
|
||||
<java-symbol type="string" name="capital_on" />
|
||||
<java-symbol type="string" name="cfTemplateForwarded" />
|
||||
<java-symbol type="string" name="cfTemplateForwardedTime" />
|
||||
<java-symbol type="string" name="cfTemplateNotForwarded" />
|
||||
<java-symbol type="string" name="cfTemplateRegistered" />
|
||||
<java-symbol type="string" name="cfTemplateRegisteredTime" />
|
||||
<java-symbol type="string" name="chooseActivity" />
|
||||
<java-symbol type="string" name="checked" />
|
||||
<java-symbol type="string" name="config_default_dns_server" />
|
||||
<java-symbol type="string" name="config_ethernet_iface_regex" />
|
||||
<java-symbol type="string" name="not_checked" />
|
||||
<java-symbol type="array" name="config_ethernet_interfaces" />
|
||||
<java-symbol type="array" name="config_wakeonlan_supported_interfaces" />
|
||||
<java-symbol type="string" name="cellbroadcast_default_package" />
|
||||
|
||||
Reference in New Issue
Block a user