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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user