Skip to content

Commit a2b41b4

Browse files
committed
NumberPicker showing IME when its input field gains focus.
1. The NumberPicker was showing the IME if the input field gets focus and hiding it when the the arrows are pressed. The leads to a nasty behavior when the input is the first focusable and the uses presser an arrow button. In such a case the IME shows and hides on every arrow press pushing the window content up and down - this looks pretty ugly. Now the IME is show on double tap of the input field. 2. The NumberPicker input now by default has an IME action done, hence after editing it the IME goes away. 3. The NumberPicker input now clears focus when it gets IME action done, so the last picker in a sequence does not show selection which is focus driven. 4. NumberPicker was incorrectly detecting double tap to begin edit and it was possble to start edit on singe tap if the user has double tapped before to start an edit. Now double tap detection is using the double tap timeout correctly. bug:6071977 Change-Id: I0ff5a491064e51663b3abec675d839d0a65b986a
1 parent 85cb9de commit a2b41b4

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

core/java/android/widget/NumberPicker.java

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import android.view.accessibility.AccessibilityEvent;
4949
import android.view.accessibility.AccessibilityManager;
5050
import android.view.animation.DecelerateInterpolator;
51+
import android.view.inputmethod.EditorInfo;
5152
import android.view.inputmethod.InputMethodManager;
5253

5354
import com.android.internal.R;
@@ -367,9 +368,9 @@ public String format(int value) {
367368
private float mLastMotionEventY;
368369

369370
/**
370-
* Flag if to begin edit on next up event.
371+
* Flag if to check for double tap and potentially start edit.
371372
*/
372-
private boolean mBeginEditOnUpEvent;
373+
private boolean mCheckBeginEditOnUpEvent;
373374

374375
/**
375376
* Flag if to adjust the selector wheel on next up event.
@@ -446,6 +447,11 @@ public String format(int value) {
446447
*/
447448
private boolean mScrollWheelAndFadingEdgesInitialized;
448449

450+
/**
451+
* The time of the last up event.
452+
*/
453+
private long mLastUpEventTimeMillis;
454+
449455
/**
450456
* Interface to listen for changes of the current value.
451457
*/
@@ -624,10 +630,6 @@ public boolean onLongClick(View v) {
624630
public void onFocusChange(View v, boolean hasFocus) {
625631
if (hasFocus) {
626632
mInputText.selectAll();
627-
InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
628-
if (inputMethodManager != null) {
629-
inputMethodManager.showSoftInput(mInputText, 0);
630-
}
631633
} else {
632634
mInputText.setSelection(0, 0);
633635
validateInputTextView(v);
@@ -639,6 +641,7 @@ public void onFocusChange(View v, boolean hasFocus) {
639641
});
640642

641643
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
644+
mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
642645

643646
// initialize constants
644647
mTouchSlop = ViewConfiguration.getTapTimeout();
@@ -773,7 +776,7 @@ public boolean onInterceptTouchEvent(MotionEvent event) {
773776
removeAllCallbacks();
774777
mShowInputControlsAnimator.cancel();
775778
mDimSelectorWheelAnimator.cancel();
776-
mBeginEditOnUpEvent = false;
779+
mCheckBeginEditOnUpEvent = false;
777780
mAdjustScrollerOnUpEvent = true;
778781
if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
779782
mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
@@ -784,7 +787,7 @@ public boolean onInterceptTouchEvent(MotionEvent event) {
784787
mAdjustScroller.forceFinished(true);
785788
onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
786789
}
787-
mBeginEditOnUpEvent = scrollersFinished;
790+
mCheckBeginEditOnUpEvent = scrollersFinished;
788791
mAdjustScrollerOnUpEvent = true;
789792
hideInputControls();
790793
return true;
@@ -801,7 +804,7 @@ public boolean onInterceptTouchEvent(MotionEvent event) {
801804
float currentMoveY = event.getY();
802805
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
803806
if (deltaDownY > mTouchSlop) {
804-
mBeginEditOnUpEvent = false;
807+
mCheckBeginEditOnUpEvent = false;
805808
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
806809
setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
807810
hideInputControls();
@@ -825,11 +828,11 @@ public boolean onTouchEvent(MotionEvent ev) {
825828
switch (action) {
826829
case MotionEvent.ACTION_MOVE:
827830
float currentMoveY = ev.getY();
828-
if (mBeginEditOnUpEvent
831+
if (mCheckBeginEditOnUpEvent
829832
|| mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
830833
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
831834
if (deltaDownY > mTouchSlop) {
832-
mBeginEditOnUpEvent = false;
835+
mCheckBeginEditOnUpEvent = false;
833836
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
834837
}
835838
}
@@ -839,11 +842,20 @@ public boolean onTouchEvent(MotionEvent ev) {
839842
mLastMotionEventY = currentMoveY;
840843
break;
841844
case MotionEvent.ACTION_UP:
842-
if (mBeginEditOnUpEvent) {
843-
setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
844-
showInputControls(mShowInputControlsAnimimationDuration);
845-
mInputText.requestFocus();
846-
return true;
845+
if (mCheckBeginEditOnUpEvent) {
846+
mCheckBeginEditOnUpEvent = false;
847+
final long deltaTapTimeMillis = ev.getEventTime() - mLastUpEventTimeMillis;
848+
if (deltaTapTimeMillis < ViewConfiguration.getDoubleTapTimeout()) {
849+
setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
850+
showInputControls(mShowInputControlsAnimimationDuration);
851+
mInputText.requestFocus();
852+
InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
853+
if (inputMethodManager != null) {
854+
inputMethodManager.showSoftInput(mInputText, 0);
855+
}
856+
mLastUpEventTimeMillis = ev.getEventTime();
857+
return true;
858+
}
847859
}
848860
VelocityTracker velocityTracker = mVelocityTracker;
849861
velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
@@ -862,6 +874,7 @@ public boolean onTouchEvent(MotionEvent ev) {
862874
}
863875
mVelocityTracker.recycle();
864876
mVelocityTracker = null;
877+
mLastUpEventTimeMillis = ev.getEventTime();
865878
break;
866879
}
867880
return true;
@@ -1985,4 +1998,22 @@ public void run() {
19851998
postDelayed(this, mLongPressUpdateInterval);
19861999
}
19872000
}
2001+
2002+
/**
2003+
* @hide
2004+
*/
2005+
public static class CustomEditText extends EditText {
2006+
2007+
public CustomEditText(Context context, AttributeSet attrs) {
2008+
super(context, attrs);
2009+
}
2010+
2011+
@Override
2012+
public void onEditorAction(int actionCode) {
2013+
super.onEditorAction(actionCode);
2014+
if (actionCode == EditorInfo.IME_ACTION_DONE) {
2015+
clearFocus();
2016+
}
2017+
}
2018+
}
19882019
}

core/res/res/layout/number_picker.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
style="?android:attr/numberPickerUpButtonStyle"
2626
android:contentDescription="@string/number_picker_increment_button" />
2727

28-
<EditText android:id="@+id/numberpicker_input"
28+
<view class="android.widget.NumberPicker$CustomEditText"
29+
android:id="@+id/numberpicker_input"
2930
android:layout_width="fill_parent"
3031
android:layout_height="wrap_content"
3132
style="?android:attr/numberPickerInputTextStyle" />

0 commit comments

Comments
 (0)