From a53efe9923bedab4fe5d578f32eaff308e5b9e76 Mon Sep 17 00:00:00 2001 From: Svetoslav Ganov Date: Thu, 8 Sep 2011 18:08:36 -0700 Subject: [PATCH] The time and data pickers did not support IME editor action correctly. 1. Updated TextView to traverse all focusable items. It was searching focus down and up and was missing right and left focusabled. Updated the focus seach to use FOCUS_FORWARD and FOCUS_BACKWARD - now all focusable views are visited. 2. TimePicker and DatePicker were not specifying the IME options for the next and done editor actions. bug:5264046 Change-Id: Ief80863fc312582f2f76928bf6e915f620c427e5 --- core/java/android/widget/DatePicker.java | 65 ++++++++++++++++++++---------- core/java/android/widget/NumberPicker.java | 7 ++-- core/java/android/widget/TextView.java | 13 +++--- core/java/android/widget/TimePicker.java | 11 ++++- 4 files changed, 64 insertions(+), 32 deletions(-) diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index 3b67f4470957..5077be6d2623 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -31,6 +31,7 @@ import android.util.SparseArray; import android.view.LayoutInflater; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import android.view.inputmethod.EditorInfo; import android.widget.NumberPicker.OnValueChangeListener; import com.android.internal.R; @@ -81,10 +82,10 @@ public class DatePicker extends FrameLayout { private static final boolean DEFAULT_ENABLED_STATE = true; - private final NumberPicker mDaySpinner; - private final LinearLayout mSpinners; + private final NumberPicker mDaySpinner; + private final NumberPicker mMonthSpinner; private final NumberPicker mYearSpinner; @@ -481,16 +482,20 @@ public class DatePicker extends FrameLayout { private void reorderSpinners() { mSpinners.removeAllViews(); char[] order = DateFormat.getDateFormatOrder(getContext()); - for (int i = 0; i < order.length; i++) { + final int spinnerCount = order.length; + for (int i = 0; i < spinnerCount; i++) { switch (order[i]) { case DateFormat.DATE: mSpinners.addView(mDaySpinner); + setImeOptions(mDaySpinner, spinnerCount, i); break; case DateFormat.MONTH: mSpinners.addView(mMonthSpinner); + setImeOptions(mMonthSpinner, spinnerCount, i); break; case DateFormat.YEAR: mSpinners.addView(mYearSpinner); + setImeOptions(mYearSpinner, spinnerCount, i); break; default: throw new IllegalArgumentException(); @@ -669,6 +674,42 @@ public class DatePicker extends FrameLayout { } /** + * Sets the IME options for a spinner based on its ordering. + * + * @param spinner The spinner. + * @param spinnerCount The total spinner count. + * @param spinnerIndex The index of the given spinner. + */ + private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) { + final int imeOptions; + if (spinnerIndex < spinnerCount - 1) { + imeOptions = EditorInfo.IME_ACTION_NEXT; + } else { + imeOptions = EditorInfo.IME_ACTION_DONE; + } + TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input); + input.setImeOptions(imeOptions); + } + + private void setContentDescriptions() { + // Day + String text = mContext.getString(R.string.date_picker_increment_day_button); + mDaySpinner.findViewById(R.id.increment).setContentDescription(text); + text = mContext.getString(R.string.date_picker_decrement_day_button); + mDaySpinner.findViewById(R.id.decrement).setContentDescription(text); + // Month + text = mContext.getString(R.string.date_picker_increment_month_button); + mMonthSpinner.findViewById(R.id.increment).setContentDescription(text); + text = mContext.getString(R.string.date_picker_decrement_month_button); + mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text); + // Year + text = mContext.getString(R.string.date_picker_increment_year_button); + mYearSpinner.findViewById(R.id.increment).setContentDescription(text); + text = mContext.getString(R.string.date_picker_decrement_year_button); + mYearSpinner.findViewById(R.id.decrement).setContentDescription(text); + } + + /** * Class for managing state storing/restoring. */ private static class SavedState extends BaseSavedState { @@ -720,22 +761,4 @@ public class DatePicker extends FrameLayout { } }; } - - private void setContentDescriptions() { - // Day - String text = mContext.getString(R.string.date_picker_increment_day_button); - mDaySpinner.findViewById(R.id.increment).setContentDescription(text); - text = mContext.getString(R.string.date_picker_decrement_day_button); - mDaySpinner.findViewById(R.id.decrement).setContentDescription(text); - // Month - text = mContext.getString(R.string.date_picker_increment_month_button); - mMonthSpinner.findViewById(R.id.increment).setContentDescription(text); - text = mContext.getString(R.string.date_picker_decrement_month_button); - mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text); - // Year - text = mContext.getString(R.string.date_picker_increment_year_button); - mYearSpinner.findViewById(R.id.increment).setContentDescription(text); - text = mContext.getString(R.string.date_picker_decrement_year_button); - mYearSpinner.findViewById(R.id.decrement).setContentDescription(text); - } } diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 35e48f228fec..5345fa4d722b 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -33,7 +33,6 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Paint.Align; import android.graphics.drawable.Drawable; -import android.os.SystemClock; import android.text.InputFilter; import android.text.InputType; import android.text.Spanned; @@ -517,7 +516,10 @@ public class NumberPicker extends LinearLayout { mInputText = (EditText) findViewById(R.id.numberpicker_input); mInputText.setOnFocusChangeListener(new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { + if (hasFocus) { + mInputText.selectAll(); + } else { + mInputText.setSelection(0, 0); validateInputTextView(v); } } @@ -687,7 +689,6 @@ public class NumberPicker extends LinearLayout { InputMethodManager imm = (InputMethodManager) getContext().getSystemService( Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mInputText, 0); - mInputText.setSelection(0, mInputText.getText().length()); return true; } VelocityTracker velocityTracker = mVelocityTracker; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index c61aad1f40c5..ace607bc23b3 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3726,19 +3726,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // instead turning this into the normal enter key codes that an // app may be expecting. if (actionCode == EditorInfo.IME_ACTION_NEXT) { - View v = focusSearch(FOCUS_DOWN); + View v = focusSearch(FOCUS_FORWARD); if (v != null) { - if (!v.requestFocus(FOCUS_DOWN)) { + if (!v.requestFocus(FOCUS_FORWARD)) { throw new IllegalStateException("focus search returned a view " + "that wasn't able to take focus!"); } } return; - + } else if (actionCode == EditorInfo.IME_ACTION_PREVIOUS) { - View v = focusSearch(FOCUS_UP); + View v = focusSearch(FOCUS_BACKWARD); if (v != null) { - if (!v.requestFocus(FOCUS_UP)) { + if (!v.requestFocus(FOCUS_BACKWARD)) { throw new IllegalStateException("focus search returned a view " + "that wasn't able to take focus!"); } @@ -3750,10 +3750,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (imm != null && imm.isActive(this)) { imm.hideSoftInputFromWindow(getWindowToken(), 0); } + clearFocus(); return; } } - + Handler h = getHandler(); if (h != null) { long eventTime = SystemClock.uptimeMillis(); diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 23502299c7c1..7865d5008f04 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -16,8 +16,6 @@ package android.widget; -import com.android.internal.R; - import android.annotation.Widget; import android.content.Context; import android.content.res.Configuration; @@ -30,8 +28,11 @@ import android.view.LayoutInflater; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import android.view.inputmethod.EditorInfo; import android.widget.NumberPicker.OnValueChangeListener; +import com.android.internal.R; + import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Locale; @@ -149,6 +150,8 @@ public class TimePicker extends FrameLayout { onTimeChanged(); } }); + EditText hourInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input); + hourInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); // divider (only for the new widget style) mDivider = (TextView) findViewById(R.id.divider); @@ -184,6 +187,8 @@ public class TimePicker extends FrameLayout { onTimeChanged(); } }); + EditText minuteInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input); + minuteInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); /* Get the localized am/pm strings and use them in the spinner */ mAmPmStrings = new DateFormatSymbols().getAmPmStrings(); @@ -214,6 +219,8 @@ public class TimePicker extends FrameLayout { } }); } + EditText amPmInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input); + amPmInput.setImeOptions(EditorInfo.IME_ACTION_DONE); // update controls to initial state updateHourControl(); -- 2.11.0