summaryrefslogtreecommitdiff
path: root/core/java/android/widget/NumberPicker.java
diff options
context:
space:
mode:
authorPhil Weaver <pweaver@google.com>2017-06-06 10:48:47 -0700
committerPhil Weaver <pweaver@google.com>2017-06-06 10:48:47 -0700
commit2b94bbed69b5c78b7acd86faf5c74cb2ddd420df (patch)
treea88d7760676e23d692bd88884be107532cfff39c /core/java/android/widget/NumberPicker.java
parentdf99c779fa6d6ec428957145aa0348ed3bcbadce (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. This CL re-merges change I459d37d4a54c91e1cb5c7ec68fe0f012b25fb740 but includes a fix to hide the visibility of the input text field whenever the keyboard needs to be hidden, even if the keyboard is not being shown or the text box isn't active. That removes an undesirable visual side-effect of the previous change. This CL also has a more correct decision about when to send a text change accessibility event. Bug: 21494380 Bug: 37016501 Test: Ran NumberPicker CTS, including a new change. Change-Id: I04c49ddc2f877cd019ee355c722c81dcd3ba0dda
Diffstat (limited to 'core/java/android/widget/NumberPicker.java')
-rw-r--r--core/java/android/widget/NumberPicker.java55
1 files changed, 41 insertions, 14 deletions
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 7bdd6dadf415..4d3189efa64e 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
@@ -1281,9 +1290,9 @@ public class NumberPicker extends LinearLayout {
InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) {
inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
- if (mHasSelectorWheel) {
- mInputText.setVisibility(View.INVISIBLE);
- }
+ }
+ if (mHasSelectorWheel) {
+ mInputText.setVisibility(View.INVISIBLE);
}
}
@@ -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 (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ 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;