diff options
| author | Phil Weaver <pweaver@google.com> | 2017-06-06 10:48:47 -0700 |
|---|---|---|
| committer | Phil Weaver <pweaver@google.com> | 2017-06-06 10:48:47 -0700 |
| commit | 2b94bbed69b5c78b7acd86faf5c74cb2ddd420df (patch) | |
| tree | a88d7760676e23d692bd88884be107532cfff39c /core/java/android/widget/NumberPicker.java | |
| parent | df99c779fa6d6ec428957145aa0348ed3bcbadce (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.java | 55 |
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; |
