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
This commit is contained in:
Svetoslav Ganov
2012-02-27 15:53:32 -08:00
parent 85cb9dece2
commit a2b41b438d
2 changed files with 49 additions and 17 deletions

View File

@@ -48,6 +48,7 @@ import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import com.android.internal.R;
@@ -367,9 +368,9 @@ public class NumberPicker extends LinearLayout {
private float mLastMotionEventY;
/**
* Flag if to begin edit on next up event.
* Flag if to check for double tap and potentially start edit.
*/
private boolean mBeginEditOnUpEvent;
private boolean mCheckBeginEditOnUpEvent;
/**
* Flag if to adjust the selector wheel on next up event.
@@ -446,6 +447,11 @@ public class NumberPicker extends LinearLayout {
*/
private boolean mScrollWheelAndFadingEdgesInitialized;
/**
* The time of the last up event.
*/
private long mLastUpEventTimeMillis;
/**
* Interface to listen for changes of the current value.
*/
@@ -624,10 +630,6 @@ public class NumberPicker extends LinearLayout {
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
mInputText.selectAll();
InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
if (inputMethodManager != null) {
inputMethodManager.showSoftInput(mInputText, 0);
}
} else {
mInputText.setSelection(0, 0);
validateInputTextView(v);
@@ -639,6 +641,7 @@ public class NumberPicker extends LinearLayout {
});
mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
// initialize constants
mTouchSlop = ViewConfiguration.getTapTimeout();
@@ -773,7 +776,7 @@ public class NumberPicker extends LinearLayout {
removeAllCallbacks();
mShowInputControlsAnimator.cancel();
mDimSelectorWheelAnimator.cancel();
mBeginEditOnUpEvent = false;
mCheckBeginEditOnUpEvent = false;
mAdjustScrollerOnUpEvent = true;
if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
@@ -784,7 +787,7 @@ public class NumberPicker extends LinearLayout {
mAdjustScroller.forceFinished(true);
onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
mBeginEditOnUpEvent = scrollersFinished;
mCheckBeginEditOnUpEvent = scrollersFinished;
mAdjustScrollerOnUpEvent = true;
hideInputControls();
return true;
@@ -801,7 +804,7 @@ public class NumberPicker extends LinearLayout {
float currentMoveY = event.getY();
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
mCheckBeginEditOnUpEvent = false;
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
hideInputControls();
@@ -825,11 +828,11 @@ public class NumberPicker extends LinearLayout {
switch (action) {
case MotionEvent.ACTION_MOVE:
float currentMoveY = ev.getY();
if (mBeginEditOnUpEvent
if (mCheckBeginEditOnUpEvent
|| mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
mCheckBeginEditOnUpEvent = false;
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
}
}
@@ -839,11 +842,20 @@ public class NumberPicker extends LinearLayout {
mLastMotionEventY = currentMoveY;
break;
case MotionEvent.ACTION_UP:
if (mBeginEditOnUpEvent) {
setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
showInputControls(mShowInputControlsAnimimationDuration);
mInputText.requestFocus();
return true;
if (mCheckBeginEditOnUpEvent) {
mCheckBeginEditOnUpEvent = false;
final long deltaTapTimeMillis = ev.getEventTime() - mLastUpEventTimeMillis;
if (deltaTapTimeMillis < ViewConfiguration.getDoubleTapTimeout()) {
setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
showInputControls(mShowInputControlsAnimimationDuration);
mInputText.requestFocus();
InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
if (inputMethodManager != null) {
inputMethodManager.showSoftInput(mInputText, 0);
}
mLastUpEventTimeMillis = ev.getEventTime();
return true;
}
}
VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
@@ -862,6 +874,7 @@ public class NumberPicker extends LinearLayout {
}
mVelocityTracker.recycle();
mVelocityTracker = null;
mLastUpEventTimeMillis = ev.getEventTime();
break;
}
return true;
@@ -1985,4 +1998,22 @@ public class NumberPicker extends LinearLayout {
postDelayed(this, mLongPressUpdateInterval);
}
}
/**
* @hide
*/
public static class CustomEditText extends EditText {
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onEditorAction(int actionCode) {
super.onEditorAction(actionCode);
if (actionCode == EditorInfo.IME_ACTION_DONE) {
clearFocus();
}
}
}
}

View File

@@ -25,7 +25,8 @@
style="?android:attr/numberPickerUpButtonStyle"
android:contentDescription="@string/number_picker_increment_button" />
<EditText android:id="@+id/numberpicker_input"
<view class="android.widget.NumberPicker$CustomEditText"
android:id="@+id/numberpicker_input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/numberPickerInputTextStyle" />