2727import android .view .LayoutInflater ;
2828import android .view .View ;
2929import android .view .accessibility .AccessibilityEvent ;
30- import android .view .accessibility .AccessibilityManager ;
3130import android .view .inputmethod .EditorInfo ;
31+ import android .view .inputmethod .InputMethodManager ;
3232import android .widget .NumberPicker .OnValueChangeListener ;
3333
3434import com .android .internal .R ;
@@ -79,6 +79,12 @@ public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
7979
8080 private final NumberPicker mAmPmSpinner ;
8181
82+ private final EditText mHourSpinnerInput ;
83+
84+ private final EditText mMinuteSpinnerInput ;
85+
86+ private final EditText mAmPmSpinnerInput ;
87+
8288 private final TextView mDivider ;
8389
8490 // Note that the legacy implementation of the TimePicker is
@@ -140,6 +146,7 @@ public TimePicker(Context context, AttributeSet attrs, int defStyle) {
140146 mHourSpinner = (NumberPicker ) findViewById (R .id .hour );
141147 mHourSpinner .setOnValueChangedListener (new NumberPicker .OnValueChangeListener () {
142148 public void onValueChange (NumberPicker spinner , int oldVal , int newVal ) {
149+ updateInputState ();
143150 if (!is24HourView ()) {
144151 if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY )
145152 || (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1 )) {
@@ -150,8 +157,8 @@ public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
150157 onTimeChanged ();
151158 }
152159 });
153- EditText hourInput = (EditText ) mHourSpinner .findViewById (R .id .numberpicker_input );
154- hourInput .setImeOptions (EditorInfo .IME_ACTION_NEXT );
160+ mHourSpinnerInput = (EditText ) mHourSpinner .findViewById (R .id .numberpicker_input );
161+ mHourSpinnerInput .setImeOptions (EditorInfo .IME_ACTION_NEXT );
155162
156163 // divider (only for the new widget style)
157164 mDivider = (TextView ) findViewById (R .id .divider );
@@ -167,6 +174,7 @@ public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
167174 mMinuteSpinner .setFormatter (NumberPicker .TWO_DIGIT_FORMATTER );
168175 mMinuteSpinner .setOnValueChangedListener (new NumberPicker .OnValueChangeListener () {
169176 public void onValueChange (NumberPicker spinner , int oldVal , int newVal ) {
177+ updateInputState ();
170178 int minValue = mMinuteSpinner .getMinValue ();
171179 int maxValue = mMinuteSpinner .getMaxValue ();
172180 if (oldVal == maxValue && newVal == minValue ) {
@@ -187,8 +195,8 @@ public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
187195 onTimeChanged ();
188196 }
189197 });
190- EditText minuteInput = (EditText ) mMinuteSpinner .findViewById (R .id .numberpicker_input );
191- minuteInput .setImeOptions (EditorInfo .IME_ACTION_NEXT );
198+ mMinuteSpinnerInput = (EditText ) mMinuteSpinner .findViewById (R .id .numberpicker_input );
199+ mMinuteSpinnerInput .setImeOptions (EditorInfo .IME_ACTION_NEXT );
192200
193201 /* Get the localized am/pm strings and use them in the spinner */
194202 mAmPmStrings = new DateFormatSymbols ().getAmPmStrings ();
@@ -197,6 +205,7 @@ public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
197205 View amPmView = findViewById (R .id .amPm );
198206 if (amPmView instanceof Button ) {
199207 mAmPmSpinner = null ;
208+ mAmPmSpinnerInput = null ;
200209 mAmPmButton = (Button ) amPmView ;
201210 mAmPmButton .setOnClickListener (new OnClickListener () {
202211 public void onClick (View button ) {
@@ -213,13 +222,14 @@ public void onClick(View button) {
213222 mAmPmSpinner .setDisplayedValues (mAmPmStrings );
214223 mAmPmSpinner .setOnValueChangedListener (new OnValueChangeListener () {
215224 public void onValueChange (NumberPicker picker , int oldVal , int newVal ) {
225+ updateInputState ();
216226 picker .requestFocus ();
217227 mIsAm = !mIsAm ;
218228 updateAmPmControl ();
219229 }
220230 });
221- EditText amPmInput = (EditText ) mAmPmSpinner .findViewById (R .id .numberpicker_input );
222- amPmInput .setImeOptions (EditorInfo .IME_ACTION_DONE );
231+ mAmPmSpinnerInput = (EditText ) mAmPmSpinner .findViewById (R .id .numberpicker_input );
232+ mAmPmSpinnerInput .setImeOptions (EditorInfo .IME_ACTION_DONE );
223233 }
224234
225235 // update controls to initial state
@@ -319,7 +329,7 @@ public void writeToParcel(Parcel dest, int flags) {
319329 dest .writeInt (mMinute );
320330 }
321331
322- @ SuppressWarnings ("unused" )
332+ @ SuppressWarnings ({ "unused" , "hiding" } )
323333 public static final Parcelable .Creator <SavedState > CREATOR = new Creator <SavedState >() {
324334 public SavedState createFromParcel (Parcel in ) {
325335 return new SavedState (in );
@@ -524,4 +534,25 @@ private void setContentDescriptions() {
524534 mAmPmSpinner .findViewById (R .id .decrement ).setContentDescription (text );
525535 }
526536 }
537+
538+ private void updateInputState () {
539+ // Make sure that if the user changes the value and the IME is active
540+ // for one of the inputs if this widget, the IME is closed. If the user
541+ // changed the value via the IME and there is a next input the IME will
542+ // be shown, otherwise the user chose another means of changing the
543+ // value and having the IME up makes no sense.
544+ InputMethodManager inputMethodManager = InputMethodManager .peekInstance ();
545+ if (inputMethodManager != null ) {
546+ if (inputMethodManager .isActive (mHourSpinnerInput )) {
547+ mHourSpinnerInput .clearFocus ();
548+ inputMethodManager .hideSoftInputFromWindow (getWindowToken (), 0 );
549+ } else if (inputMethodManager .isActive (mMinuteSpinnerInput )) {
550+ mMinuteSpinnerInput .clearFocus ();
551+ inputMethodManager .hideSoftInputFromWindow (getWindowToken (), 0 );
552+ } else if (inputMethodManager .isActive (mAmPmSpinnerInput )) {
553+ mAmPmSpinnerInput .clearFocus ();
554+ inputMethodManager .hideSoftInputFromWindow (getWindowToken (), 0 );
555+ }
556+ }
557+ }
527558}
0 commit comments