summaryrefslogtreecommitdiff
path: root/core/java/android/widget/NumberPicker.java
diff options
context:
space:
mode:
authorPhil Weaver <pweaver@google.com>2017-04-26 12:58:15 -0700
committerPhil Weaver <pweaver@google.com>2017-05-02 10:43:34 -0700
commit1d359a6d3179b7e793fc4082237b001d7260c423 (patch)
tree970de8dd605bedba77d229dcc9f21f20cd1335c1 /core/java/android/widget/NumberPicker.java
parentda3dd7c0cf1fcd7e352c8f9e30519e85776c5662 (diff)
NumberPicker a11y (and a11y-inspired) fixes
- Sending scroll events for accessibility. - Sending text update events when state changes. - Blocking text updates during fling to reduce number of events. - Making widget focusable by default, which keeps focus from moving to the rest of the UI when the text box becomes invisible. - Managing visibility of the text box alongside IME state, so the IME won't decide to display the password keyboard during a fling. Bug: 21494380 Bug: 37016501 Test: Ran NumberPicker CTS Change-Id: I459d37d4a54c91e1cb5c7ec68fe0f012b25fb740
Diffstat (limited to 'core/java/android/widget/NumberPicker.java')
-rw-r--r--core/java/android/widget/NumberPicker.java49
1 files changed, 38 insertions, 11 deletions
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7bdd6dadf415..d456989eb50a 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -737,6 +737,7 @@ public class NumberPicker extends LinearLayout {
mInputText.setFilters(new InputFilter[] {
new InputTextFilter()
});
+ mInputText.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
@@ -770,6 +771,12 @@ public class NumberPicker extends LinearLayout {
if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
}
+
+ // Should be focusable by default, as the text view whose visibility changes is focusable
+ if (getFocusable() == View.FOCUSABLE_AUTO) {
+ setFocusable(View.FOCUSABLE);
+ setFocusableInTouchMode(true);
+ }
}
@Override
@@ -856,7 +863,7 @@ public class NumberPicker extends LinearLayout {
switch (action) {
case MotionEvent.ACTION_DOWN: {
removeAllCallbacks();
- mInputText.setVisibility(View.INVISIBLE);
+ hideSoftInput();
mLastDownOrMoveEventY = mLastDownEventY = event.getY();
mLastDownEventTime = event.getEventTime();
mIgnoreMoveEvents = false;
@@ -883,11 +890,9 @@ public class NumberPicker extends LinearLayout {
mFlingScroller.forceFinished(true);
mAdjustScroller.forceFinished(true);
} else if (mLastDownEventY < mTopSelectionDividerTop) {
- hideSoftInput();
postChangeCurrentByOneFromLongPress(
false, ViewConfiguration.getLongPressTimeout());
} else if (mLastDownEventY > mBottomSelectionDividerBottom) {
- hideSoftInput();
postChangeCurrentByOneFromLongPress(
true, ViewConfiguration.getLongPressTimeout());
} else {
@@ -1120,6 +1125,7 @@ public class NumberPicker extends LinearLayout {
@Override
public void scrollBy(int x, int y) {
int[] selectorIndices = mSelectorIndices;
+ int startScrollOffset = mCurrentScrollOffset;
if (!mWrapSelectorWheel && y > 0
&& selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
mCurrentScrollOffset = mInitialScrollOffset;
@@ -1147,6 +1153,9 @@ public class NumberPicker extends LinearLayout {
mCurrentScrollOffset = mInitialScrollOffset;
}
}
+ if (startScrollOffset != mCurrentScrollOffset) {
+ onScrollChanged(0, mCurrentScrollOffset, 0, startScrollOffset);
+ }
}
@Override
@@ -1735,7 +1744,10 @@ public class NumberPicker extends LinearLayout {
}
int previous = mValue;
mValue = current;
- updateInputTextView();
+ // If we're flinging, we'll update the text view at the end when it becomes visible
+ if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {
+ updateInputTextView();
+ }
if (notifyChange) {
notifyChange(previous, current);
}
@@ -1752,7 +1764,7 @@ public class NumberPicker extends LinearLayout {
*/
private void changeValueByOne(boolean increment) {
if (mHasSelectorWheel) {
- mInputText.setVisibility(View.INVISIBLE);
+ hideSoftInput();
if (!moveToFinalScrollerPosition(mFlingScroller)) {
moveToFinalScrollerPosition(mAdjustScroller);
}
@@ -1799,9 +1811,8 @@ public class NumberPicker extends LinearLayout {
*/
private void onScrollerFinished(Scroller scroller) {
if (scroller == mFlingScroller) {
- if (!ensureScrollWheelAdjusted()) {
- updateInputTextView();
- }
+ ensureScrollWheelAdjusted();
+ updateInputTextView();
onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
} else {
if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
@@ -1937,9 +1948,25 @@ public class NumberPicker extends LinearLayout {
*/
String text = (mDisplayedValues == null) ? formatNumber(mValue)
: mDisplayedValues[mValue - mMinValue];
- if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
- mInputText.setText(text);
- return true;
+ if (!TextUtils.isEmpty(text)) {
+ CharSequence beforeText = mInputText.getText();
+ if (!text.equals(beforeText.toString())) {
+ mInputText.setText(text);
+ if (mAccessibilityNodeProvider != null) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+ mInputText.onInitializeAccessibilityEvent(event);
+ mInputText.onPopulateAccessibilityEvent(event);
+ event.setFromIndex(0);
+ event.setRemovedCount(beforeText.length());
+ event.setAddedCount(text.length());
+ event.setBeforeText(beforeText);
+ event.setSource(NumberPicker.this,
+ AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT);
+ requestSendAccessibilityEvent(NumberPicker.this, event);
+ }
+ return true;
+ }
}
return false;