From 518ff0de95e64116ecb07706fc564d4c19197ca7 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Fri, 15 Aug 2014 14:20:35 -0700 Subject: Fix date and time picker styling Removes done buttons from widgets, fixes date picker day selection, fixes dialog layouts in landscape, updates colors. Adds API on AlertDialog for setting the view by resource ID, which is necessary to correctly inflate the view against the dialog's parent view. BUG: 16941550 BUG: 16852521 BUG: 16878697 BUG: 16838659 BUG: 17047435 Change-Id: I138858ce06cd4abf68a2c3361ec170370236b33b --- core/java/android/app/DatePickerDialog.java | 84 ++++++--------- core/java/android/app/TimePickerDialog.java | 120 +++++++++------------ core/java/android/widget/DatePicker.java | 61 ++++++----- .../android/widget/DatePickerCalendarDelegate.java | 55 +--------- core/java/android/widget/RadialTimePickerView.java | 7 +- core/java/android/widget/SimpleMonthView.java | 38 +++---- core/java/android/widget/TimePicker.java | 60 +++++------ .../android/widget/TimePickerClockDelegate.java | 75 +------------ .../android/widget/TimePickerSpinnerDelegate.java | 89 ++------------- core/java/android/widget/YearPickerView.java | 2 +- core/res/res/layout-land/date_picker_holo.xml | 25 +---- core/res/res/layout-land/time_picker_holo.xml | 43 ++------ core/res/res/layout-sw600dp/date_picker_holo.xml | 18 +--- core/res/res/layout/alert_dialog_material.xml | 9 +- core/res/res/layout/date_picker_done_button.xml | 33 ------ core/res/res/layout/date_picker_header_view.xml | 23 ---- core/res/res/layout/date_picker_holo.xml | 15 +-- core/res/res/layout/date_picker_selected_date.xml | 71 ++++++------ core/res/res/layout/time_header_label.xml | 31 +++--- core/res/res/layout/time_picker_dialog.xml | 3 +- core/res/res/layout/time_picker_holo.xml | 17 --- .../res/res/layout/time_picker_legacy_leanback.xml | 10 -- core/res/res/values/dimens.xml | 12 +-- core/res/res/values/styles_material.xml | 34 +++--- core/res/res/values/symbols.xml | 3 - core/res/res/values/themes_material.xml | 21 +--- 26 files changed, 301 insertions(+), 658 deletions(-) delete mode 100644 core/res/res/layout/date_picker_done_button.xml delete mode 100644 core/res/res/layout/date_picker_header_view.xml diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index a78b13726589..1e556d67d45c 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -24,8 +24,10 @@ import android.text.format.DateUtils; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; +import android.widget.Button; import android.widget.DatePicker; import android.widget.DatePicker.OnDateChangedListener; +import android.widget.DatePicker.ValidationCallback; import com.android.internal.R; @@ -49,7 +51,6 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, private final Calendar mCalendar; private boolean mTitleNeedsUpdate = true; - private boolean mIsCanceled = false; /** * The callback used to indicate the user is done filling in the date. @@ -83,7 +84,7 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, static int resolveDialogTheme(Context context, int resid) { if (resid == 0) { - TypedValue outValue = new TypedValue(); + final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.datePickerDialogTheme, outValue, true); return outValue.resourceId; } else { @@ -99,68 +100,41 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, * @param monthOfYear The initial month of the dialog. * @param dayOfMonth The initial day of the dialog. */ - public DatePickerDialog(Context context, - int theme, - OnDateSetListener listener, - int year, - int monthOfYear, - int dayOfMonth) { + public DatePickerDialog(Context context, int theme, OnDateSetListener listener, int year, + int monthOfYear, int dayOfMonth) { super(context, resolveDialogTheme(context, theme)); mDateSetListener = listener; mCalendar = Calendar.getInstance(); - Context themeContext = getContext(); - - final LayoutInflater inflater = (LayoutInflater) themeContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); + final Context themeContext = getContext(); + final LayoutInflater inflater = LayoutInflater.from(themeContext); final View view = inflater.inflate(R.layout.date_picker_dialog, null); setView(view); + setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this); + setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this); setButtonPanelLayoutHint(LAYOUT_HINT_SIDE); - // Initialize state mDatePicker = (DatePicker) view.findViewById(R.id.datePicker); - mDatePicker.setShowDoneButton(true); - mDatePicker.setDismissCallback(new DatePicker.DatePickerDismissCallback() { - @Override - public void dismiss(DatePicker view, boolean isCancel, int year, int month, int dayOfMonth) { - mIsCanceled = isCancel; - if (!isCancel) { - mDateSetListener.onDateSet(view, year, month, dayOfMonth); - } - DatePickerDialog.this.dismiss(); - } - }); mDatePicker.init(year, monthOfYear, dayOfMonth, this); - } - - public void onClick(DialogInterface dialog, int which) { - tryNotifyDateSet(); + mDatePicker.setValidationCallback(mValidationCallback); } @Override - public void cancel() { - mIsCanceled = true; - super.cancel(); - } - - @Override - protected void onStop() { - tryNotifyDateSet(); - super.onStop(); - } - - public void onDateChanged(DatePicker view, int year, - int month, int day) { + public void onDateChanged(DatePicker view, int year, int month, int day) { mDatePicker.init(year, month, day, this); updateTitle(year, month, day); } - private void tryNotifyDateSet() { - if (mDateSetListener != null && !mIsCanceled) { - mDatePicker.clearFocus(); - mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(), - mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case BUTTON_POSITIVE: + if (mDateSetListener != null) { + mDateSetListener.onDateSet(mDatePicker, mDatePicker.getYear(), + mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); + } + break; } } @@ -208,7 +182,7 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, @Override public Bundle onSaveInstanceState() { - Bundle state = super.onSaveInstanceState(); + final Bundle state = super.onSaveInstanceState(); state.putInt(YEAR, mDatePicker.getYear()); state.putInt(MONTH, mDatePicker.getMonth()); state.putInt(DAY, mDatePicker.getDayOfMonth()); @@ -218,9 +192,19 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - int year = savedInstanceState.getInt(YEAR); - int month = savedInstanceState.getInt(MONTH); - int day = savedInstanceState.getInt(DAY); + final int year = savedInstanceState.getInt(YEAR); + final int month = savedInstanceState.getInt(MONTH); + final int day = savedInstanceState.getInt(DAY); mDatePicker.init(year, month, day, this); } + + private final ValidationCallback mValidationCallback = new ValidationCallback() { + @Override + public void onValidationChanged(boolean valid) { + final Button positive = getButton(BUTTON_POSITIVE); + if (positive != null) { + positive.setEnabled(valid); + } + } + }; } diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java index a2f30508c387..697c5d8f4b67 100644 --- a/core/java/android/app/TimePickerDialog.java +++ b/core/java/android/app/TimePickerDialog.java @@ -19,13 +19,14 @@ package android.app; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; -import android.os.Build; import android.os.Bundle; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; +import android.widget.Button; import android.widget.TimePicker; import android.widget.TimePicker.OnTimeChangedListener; +import android.widget.TimePicker.ValidationCallback; import com.android.internal.R; @@ -35,8 +36,19 @@ import com.android.internal.R; *

See the Pickers * guide.

*/ -public class TimePickerDialog extends AlertDialog - implements OnClickListener, OnTimeChangedListener { +public class TimePickerDialog extends AlertDialog implements OnClickListener, + OnTimeChangedListener { + + private static final String HOUR = "hour"; + private static final String MINUTE = "minute"; + private static final String IS_24_HOUR = "is24hour"; + + private final TimePicker mTimePicker; + private final OnTimeSetListener mTimeSetCallback; + + private final int mInitialHourOfDay; + private final int mInitialMinute; + private final boolean mIs24HourView; /** * The callback interface used to indicate the user is done filling in @@ -52,19 +64,6 @@ public class TimePickerDialog extends AlertDialog void onTimeSet(TimePicker view, int hourOfDay, int minute); } - private static final String HOUR = "hour"; - private static final String MINUTE = "minute"; - private static final String IS_24_HOUR = "is24hour"; - - private final TimePicker mTimePicker; - private final OnTimeSetListener mTimeSetCallback; - - int mInitialHourOfDay; - int mInitialMinute; - boolean mIs24HourView; - - private boolean mIsCanceled; - /** * @param context Parent. * @param callBack How parent is notified. @@ -80,7 +79,7 @@ public class TimePickerDialog extends AlertDialog static int resolveDialogTheme(Context context, int resid) { if (resid == 0) { - TypedValue outValue = new TypedValue(); + final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true); return outValue.resourceId; } else { @@ -96,10 +95,8 @@ public class TimePickerDialog extends AlertDialog * @param minute The initial minute. * @param is24HourView Whether this is a 24 hour view, or AM/PM. */ - public TimePickerDialog(Context context, - int theme, - OnTimeSetListener callBack, - int hourOfDay, int minute, boolean is24HourView) { + public TimePickerDialog(Context context, int theme, OnTimeSetListener callBack, int hourOfDay, + int minute, boolean is24HourView) { super(context, resolveDialogTheme(context, theme)); mTimeSetCallback = callBack; @@ -108,72 +105,51 @@ public class TimePickerDialog extends AlertDialog mIs24HourView = is24HourView; final Context themeContext = getContext(); - - final int targetSdkVersion = themeContext.getApplicationInfo().targetSdkVersion; - if (targetSdkVersion < Build.VERSION_CODES.L) { - setIcon(0); - setTitle(R.string.time_picker_dialog_title); - } - final LayoutInflater inflater = LayoutInflater.from(themeContext); final View view = inflater.inflate(R.layout.time_picker_dialog, null); setView(view); + setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this); + setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this); mTimePicker = (TimePicker) view.findViewById(R.id.timePicker); - mTimePicker.setShowDoneButton(true); - // If time picker layout has no done button, add a dialog button. - if (!mTimePicker.isShowDoneButton()) { - setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this); - } - - mTimePicker.setDismissCallback(new TimePicker.TimePickerDismissCallback() { - @Override - public void dismiss(TimePicker view, boolean isCancel, int hourOfDay, int minute) { - mIsCanceled = isCancel; - if (!isCancel) { - mTimeSetCallback.onTimeSet(view, hourOfDay, minute); - TimePickerDialog.this.dismiss(); - } else { - TimePickerDialog.this.cancel(); - } - } - }); mTimePicker.setIs24HourView(mIs24HourView); mTimePicker.setCurrentHour(mInitialHourOfDay); mTimePicker.setCurrentMinute(mInitialMinute); mTimePicker.setOnTimeChangedListener(this); + mTimePicker.setValidationCallback(mValidationCallback); } - public void onClick(DialogInterface dialog, int which) { - tryNotifyTimeSet(); - } - - public void updateTime(int hourOfDay, int minutOfHour) { - mTimePicker.setCurrentHour(hourOfDay); - mTimePicker.setCurrentMinute(minutOfHour); - } - + @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { /* do nothing */ } - private void tryNotifyTimeSet() { - if (mTimeSetCallback != null && !mIsCanceled) { - mTimePicker.clearFocus(); - mTimeSetCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), - mTimePicker.getCurrentMinute()); + @Override + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case BUTTON_POSITIVE: + if (mTimeSetCallback != null) { + mTimeSetCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), + mTimePicker.getCurrentMinute()); + } + break; } } - @Override - protected void onStop() { - tryNotifyTimeSet(); - super.onStop(); + /** + * Sets the current time. + * + * @param hourOfDay The current hour within the day. + * @param minuteOfHour The current minute within the hour. + */ + public void updateTime(int hourOfDay, int minuteOfHour) { + mTimePicker.setCurrentHour(hourOfDay); + mTimePicker.setCurrentMinute(minuteOfHour); } @Override public Bundle onSaveInstanceState() { - Bundle state = super.onSaveInstanceState(); + final Bundle state = super.onSaveInstanceState(); state.putInt(HOUR, mTimePicker.getCurrentHour()); state.putInt(MINUTE, mTimePicker.getCurrentMinute()); state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView()); @@ -183,10 +159,20 @@ public class TimePickerDialog extends AlertDialog @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - int hour = savedInstanceState.getInt(HOUR); - int minute = savedInstanceState.getInt(MINUTE); + final int hour = savedInstanceState.getInt(HOUR); + final int minute = savedInstanceState.getInt(MINUTE); mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR)); mTimePicker.setCurrentHour(hour); mTimePicker.setCurrentMinute(minute); } + + private final ValidationCallback mValidationCallback = new ValidationCallback() { + @Override + public void onValidationChanged(boolean valid) { + final Button positive = getButton(BUTTON_POSITIVE); + if (positive != null) { + positive.setEnabled(valid); + } + } + }; } diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index d0a2eabca962..26c1f960ff57 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -16,6 +16,7 @@ package android.widget; +import android.annotation.Nullable; import android.annotation.Widget; import android.content.Context; import android.content.res.Configuration; @@ -123,7 +124,7 @@ public class DatePicker extends FrameLayout { final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DatePicker, defStyleAttr, defStyleRes); - int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER); + final int mode = a.getInt(R.styleable.DatePicker_datePickerMode, MODE_SPINNER); a.recycle(); switch (mode) { @@ -148,20 +149,6 @@ public class DatePicker extends FrameLayout { defStyleRes); } - /** - * @hide - */ - public void setShowDoneButton(boolean showDoneButton) { - mDelegate.setShowDoneButton(showDoneButton); - } - - /** - * @hide - */ - public void setDismissCallback(DatePickerDismissCallback callback) { - mDelegate.setDismissCallback(callback); - } - /** * Initialize the state. If the provided values designate an inconsistent * date the values are normalized before updating the spinners. @@ -259,6 +246,16 @@ public class DatePicker extends FrameLayout { mDelegate.setMaxDate(maxDate); } + /** + * Sets the callback that indicates the current date is valid. + * + * @param callback the callback, may be null + * @hide + */ + public void setValidationCallback(@Nullable ValidationCallback callback) { + mDelegate.setValidationCallback(callback); + } + @Override public void setEnabled(boolean enabled) { if (mDelegate.isEnabled() == enabled) { @@ -402,8 +399,7 @@ public class DatePicker extends FrameLayout { void setSpinnersShown(boolean shown); boolean getSpinnersShown(); - void setShowDoneButton(boolean showDoneButton); - void setDismissCallback(DatePickerDismissCallback callback); + void setValidationCallback(ValidationCallback callback); void onConfigurationChanged(Configuration newConfig); @@ -431,7 +427,8 @@ public class DatePicker extends FrameLayout { protected Locale mCurrentLocale; // Callbacks - protected OnDateChangedListener mOnDateChangedListener; + protected OnDateChangedListener mOnDateChangedListener; + protected ValidationCallback mValidationCallback; public AbstractDatePickerDelegate(DatePicker delegator, Context context) { mDelegator = delegator; @@ -447,15 +444,27 @@ public class DatePicker extends FrameLayout { } mCurrentLocale = locale; } + + @Override + public void setValidationCallback(ValidationCallback callback) { + mValidationCallback = callback; + } + + protected void onValidationChanged(boolean valid) { + if (mValidationCallback != null) { + mValidationCallback.onValidationChanged(valid); + } + } } /** - * A callback interface for dismissing the DatePicker when included into a Dialog + * A callback interface for updating input validity when the date picker + * when included into a dialog. * * @hide */ - public static interface DatePickerDismissCallback { - void dismiss(DatePicker view, boolean isCancel, int year, int month, int dayOfMonth); + public static interface ValidationCallback { + void onValidationChanged(boolean valid); } /** @@ -774,16 +783,6 @@ public class DatePicker extends FrameLayout { return mSpinners.isShown(); } - @Override - public void setShowDoneButton(boolean showDoneButton) { - // Nothing to do - } - - @Override - public void setDismissCallback(DatePickerDismissCallback callback) { - // Nothing to do - } - @Override public void onConfigurationChanged(Configuration newConfig) { setCurrentLocale(newConfig.locale); diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java index c0c76acc9db1..f4a478a30727 100644 --- a/core/java/android/widget/DatePickerCalendarDelegate.java +++ b/core/java/android/widget/DatePickerCalendarDelegate.java @@ -31,11 +31,9 @@ import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.AttributeSet; import android.util.SparseArray; -import android.util.StateSet; import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.AlphaAnimation; @@ -83,8 +81,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i private DayPickerView mDayPickerView; private YearPickerView mYearPickerView; - private ViewGroup mLayoutButtons; - private boolean mIsEnabled = true; // Accessibility strings. @@ -106,11 +102,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i private Calendar mMinDate; private Calendar mMaxDate; - // For showing the done button when in a Dialog - private Button mDoneButton; - private boolean mShowDoneButton; - private DatePicker.DatePickerDismissCallback mDismissCallback; - private HashSet mListeners = new HashSet(); public DatePickerCalendarDelegate(DatePicker delegator, Context context, AttributeSet attrs, @@ -165,7 +156,7 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i R.styleable.DatePicker_headerSelectedTextColor, defaultHighlightColor); final int headerBackgroundColor = a.getColor(R.styleable.DatePicker_headerBackgroundColor, Color.TRANSPARENT); - mMonthAndDayLayout.setBackgroundColor(headerBackgroundColor); + mDateLayout.setBackgroundColor(headerBackgroundColor); final int monthTextAppearanceResId = a.getResourceId( R.styleable.DatePicker_headerMonthTextAppearance, -1); @@ -221,20 +212,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i animation2.setDuration(ANIMATION_DURATION); mAnimator.setOutAnimation(animation2); - mLayoutButtons = (ViewGroup) mainView.findViewById(R.id.layout_buttons); - mDoneButton = (Button) mainView.findViewById(R.id.done); - mDoneButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - tryVibrate(); - if (mDismissCallback != null) { - mDismissCallback.dismiss(mDelegator, false, mCurrentDate.get(Calendar.YEAR), - mCurrentDate.get(Calendar.MONTH), - mCurrentDate.get(Calendar.DAY_OF_MONTH)); - } - } - }); - updateDisplay(false); setCurrentView(MONTH_AND_DAY_VIEW); } @@ -311,9 +288,9 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i // Position the Year View at the correct location if (viewIndices[YEAR_INDEX] == 0) { - mDateLayout.addView(mHeaderYearTextView, 0); - } else { mDateLayout.addView(mHeaderYearTextView, 1); + } else { + mDateLayout.addView(mHeaderYearTextView, 2); } // Position Day and Month Views @@ -544,21 +521,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i return false; } - @Override - public void setShowDoneButton(boolean showDoneButton) { - mShowDoneButton = showDoneButton; - updateDoneButtonVisibility(); - } - - private void updateDoneButtonVisibility() { - mLayoutButtons.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE); - } - - @Override - public void setDismissCallback(DatePicker.DatePickerDismissCallback callback) { - mDismissCallback = callback; - } - @Override public void onConfigurationChanged(Configuration newConfig) { mYearFormat = new SimpleDateFormat("y", newConfig.locale); @@ -640,7 +602,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i updatePickers(); setCurrentView(MONTH_AND_DAY_VIEW); updateDisplay(true); - updateDoneButtonEnableState(); } // If the newly selected month / year does not contain the currently selected day number, @@ -684,16 +645,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i mCurrentDate.set(Calendar.DAY_OF_MONTH, day); updatePickers(); updateDisplay(true); - updateDoneButtonEnableState(); - } - - private void updateDoneButtonEnableState() { - if (mShowDoneButton) { - final boolean enabled = mCurrentDate.equals(mMinDate) || - mCurrentDate.equals(mMaxDate) || - (mCurrentDate.after(mMinDate) && mCurrentDate.before(mMaxDate)); - mDoneButton.setEnabled(enabled); - } } private void updatePickers() { diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java index 3d2f67f7c115..adca4ccdaaed 100644 --- a/core/java/android/widget/RadialTimePickerView.java +++ b/core/java/android/widget/RadialTimePickerView.java @@ -85,7 +85,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { private static final int ALPHA_TRANSPARENT = 0; // Alpha level of color for selector. - private static final int ALPHA_SELECTOR = 255; // was 51 + private static final int ALPHA_SELECTOR = 60; // was 51 // Alpha level of color for selected circle. private static final int ALPHA_AMPM_SELECTED = ALPHA_SELECTOR; @@ -105,7 +105,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { private static final int CENTER_RADIUS = 2; - private static final int[] STATE_SET_SELECTED = new int[] { R.attr.state_selected }; + private static final int[] STATE_SET_SELECTED = new int[] {R.attr.state_selected}; private static int[] sSnapPrefer30sMap = new int[361]; @@ -337,6 +337,9 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { // list doesn't have a state for selected, we'll use this color. final int amPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor, res.getColor(R.color.timepicker_default_ampm_selected_background_color_material)); + amPmBackgroundColor = ColorStateList.addFirstIfMissing( + amPmBackgroundColor, R.attr.state_selected, amPmSelectedColor); + mAmPmSelectedColor = amPmBackgroundColor.getColorForState( STATE_SET_SELECTED, amPmSelectedColor); mAmPmUnselectedColor = amPmBackgroundColor.getDefaultColor(); diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java index ab6da7c7c5ea..a0d94750aca6 100644 --- a/core/java/android/widget/SimpleMonthView.java +++ b/core/java/android/widget/SimpleMonthView.java @@ -38,10 +38,8 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.R; import com.android.internal.widget.ExploreByTouchHelper; -import java.security.InvalidParameterException; import java.util.Calendar; import java.util.Formatter; -import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -52,8 +50,8 @@ import java.util.Locale; class SimpleMonthView extends View { private static final String TAG = "SimpleMonthView"; - private static int DEFAULT_HEIGHT = 32; - private static int MIN_HEIGHT = 10; + private static final int DEFAULT_HEIGHT = 32; + private static final int MIN_HEIGHT = 10; private static final int DEFAULT_SELECTED_DAY = -1; private static final int DEFAULT_WEEK_START = Calendar.SUNDAY; @@ -63,13 +61,13 @@ class SimpleMonthView extends View { private static final int SELECTED_CIRCLE_ALPHA = 60; - private static int DAY_SEPARATOR_WIDTH = 1; + private static final int DAY_SEPARATOR_WIDTH = 1; - private int mMiniDayNumberTextSize; - private int mMonthLabelTextSize; - private int mMonthDayLabelTextSize; - private int mMonthHeaderSize; - private int mDaySelectedCircleSize; + private final int mMiniDayNumberTextSize; + private final int mMonthLabelTextSize; + private final int mMonthDayLabelTextSize; + private final int mMonthHeaderSize; + private final int mDaySelectedCircleSize; // used for scaling to the device density private static float mScale = 0; @@ -289,7 +287,7 @@ class SimpleMonthView extends View { drawDays(canvas); } - private static boolean isValidDay(int day) { + private static boolean isValidDayOfWeek(int day) { return (day >= Time.SUNDAY && day <= Time.SATURDAY); } @@ -299,7 +297,7 @@ class SimpleMonthView extends View { * default to no focus month if no value is passed in. The only required parameter is the * week start. * - * @param selectedDay the selected day. + * @param selectedDay the selected day of the month, or -1 for no selection. * @param month the month. * @param year the year. * @param weekStart which day the week should start on. {@link Time#SUNDAY} through @@ -313,9 +311,7 @@ class SimpleMonthView extends View { mRowHeight = MIN_HEIGHT; } - if (isValidDay(selectedDay)) { - mSelectedDay = selectedDay; - } + mSelectedDay = selectedDay; if (month >= Calendar.JANUARY && month <= Calendar.DECEMBER) { mMonth = month; @@ -333,7 +329,7 @@ class SimpleMonthView extends View { mCalendar.set(Calendar.DAY_OF_MONTH, 1); mDayOfWeekStart = mCalendar.get(Calendar.DAY_OF_WEEK); - if (isValidDay(weekStart)) { + if (isValidDayOfWeek(weekStart)) { mWeekStart = weekStart; } else { mWeekStart = mCalendar.getFirstDayOfWeek(); @@ -424,8 +420,8 @@ class SimpleMonthView extends View { } private void drawMonthTitle(Canvas canvas) { - int x = (mWidth + 2 * mPadding) / 2; - int y = (mMonthHeaderSize - mMonthDayLabelTextSize) / 2 + (mMonthLabelTextSize / 3); + final float x = (mWidth + 2 * mPadding) / 2f; + final float y = (mMonthHeaderSize - mMonthDayLabelTextSize) / 2f; canvas.drawText(getMonthAndYearString(), x, y, mMonthTitlePaint); } @@ -437,9 +433,9 @@ class SimpleMonthView extends View { int calendarDay = (i + mWeekStart) % mNumDays; int x = (2 * i + 1) * dayWidthHalf + mPadding; mDayLabelCalendar.set(Calendar.DAY_OF_WEEK, calendarDay); - canvas.drawText(mDayLabelCalendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, - Locale.getDefault()).toUpperCase(Locale.getDefault()), x, y, - mMonthDayLabelPaint); + canvas.drawText("" + mDayLabelCalendar.getDisplayName(Calendar.DAY_OF_WEEK, + Calendar.SHORT, Locale.getDefault()).toUpperCase(Locale.getDefault()).charAt(0), + x, y, mMonthDayLabelPaint); } } diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index c48866692190..85cf67b90e5e 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -16,6 +16,7 @@ package android.widget; +import android.annotation.Nullable; import android.annotation.Widget; import android.content.Context; import android.content.res.Configuration; @@ -80,7 +81,7 @@ public class TimePicker extends FrameLayout { final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes); - int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER); + final int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER); a.recycle(); switch (mode) { @@ -149,6 +150,16 @@ public class TimePicker extends FrameLayout { mDelegate.setOnTimeChangedListener(onTimeChangedListener); } + /** + * Sets the callback that indicates the current time is valid. + * + * @param callback the callback, may be null + * @hide + */ + public void setValidationCallback(@Nullable ValidationCallback callback) { + mDelegate.setValidationCallback(callback); + } + @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); @@ -160,27 +171,6 @@ public class TimePicker extends FrameLayout { return mDelegate.isEnabled(); } - /** - * @hide - */ - public void setShowDoneButton(boolean showDoneButton) { - mDelegate.setShowDoneButton(showDoneButton); - } - - /** - * @hide - */ - public boolean isShowDoneButton() { - return mDelegate.isShowDoneButton(); - } - - /** - * @hide - */ - public void setDismissCallback(TimePickerDismissCallback callback) { - mDelegate.setDismissCallback(callback); - } - @Override public int getBaseline() { return mDelegate.getBaseline(); @@ -244,14 +234,11 @@ public class TimePicker extends FrameLayout { boolean is24HourView(); void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener); + void setValidationCallback(ValidationCallback callback); void setEnabled(boolean enabled); boolean isEnabled(); - boolean isShowDoneButton(); - void setShowDoneButton(boolean showDoneButton); - void setDismissCallback(TimePickerDismissCallback callback); - int getBaseline(); void onConfigurationChanged(Configuration newConfig); @@ -266,12 +253,13 @@ public class TimePicker extends FrameLayout { } /** - * A callback interface for dismissing the TimePicker when included into a Dialog + * A callback interface for updating input validity when the TimePicker + * when included into a Dialog. * * @hide */ - public static interface TimePickerDismissCallback { - void dismiss(TimePicker view, boolean isCancel, int hourOfDay, int minute); + public static interface ValidationCallback { + void onValidationChanged(boolean valid); } /** @@ -288,7 +276,8 @@ public class TimePicker extends FrameLayout { protected Locale mCurrentLocale; // Callbacks - protected OnTimeChangedListener mOnTimeChangedListener; + protected OnTimeChangedListener mOnTimeChangedListener; + protected ValidationCallback mValidationCallback; public AbstractTimePickerDelegate(TimePicker delegator, Context context) { mDelegator = delegator; @@ -304,5 +293,16 @@ public class TimePicker extends FrameLayout { } mCurrentLocale = locale; } + + @Override + public void setValidationCallback(ValidationCallback callback) { + mValidationCallback = callback; + } + + protected void onValidationChanged(boolean valid) { + if (mValidationCallback != null) { + mValidationCallback.onValidationChanged(valid); + } + } } } diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java index 8102c4acf364..376e5b443f5b 100644 --- a/core/java/android/widget/TimePickerClockDelegate.java +++ b/core/java/android/widget/TimePickerClockDelegate.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; -import android.graphics.Color; import android.os.Parcel; import android.os.Parcelable; import android.text.format.DateFormat; @@ -35,7 +34,6 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import com.android.internal.R; -import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Locale; @@ -46,29 +44,20 @@ import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES; * A delegate implementing the basic TimePicker */ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { - private static final boolean DEFAULT_ENABLED_STATE = true; - private static final int HOURS_IN_HALF_DAY = 12; // state private boolean mIs24HourView; - private boolean mIsAm; // ui components private final NumberPicker mHourSpinner; - private final NumberPicker mMinuteSpinner; - private final NumberPicker mAmPmSpinner; - private final EditText mHourSpinnerInput; - private final EditText mMinuteSpinnerInput; - private final EditText mAmPmSpinnerInput; - private final TextView mDivider; // Note that the legacy implementation of the TimePicker is @@ -77,17 +66,10 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { // accommodates these two cases to be backwards compatible. private final Button mAmPmButton; - // May be null if layout has no done button - private final View mDoneButton; - private boolean mShowDoneButton; - private TimePicker.TimePickerDismissCallback mDismissCallback; - private final String[] mAmPmStrings; private boolean mIsEnabled = DEFAULT_ENABLED_STATE; - private Calendar mTempCalendar; - private boolean mHourWithTwoDigit; private char mHourFormat; @@ -227,20 +209,6 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { } } - mDoneButton = delegator.findViewById(R.id.done_button); - mShowDoneButton = (mDoneButton != null); - if (mShowDoneButton) { - mDoneButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mDismissCallback != null) { - mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), - getCurrentMinute()); - } - } - }); - } - getHourFormatData(); // update controls to initial state @@ -265,8 +233,6 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); } - - updateDoneButton(); } private void getHourFormatData() { @@ -431,30 +397,6 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { return mIsEnabled; } - @Override - public void setShowDoneButton(boolean showDoneButton) { - if (mDoneButton != null) { - mShowDoneButton = showDoneButton; - updateDoneButton(); - } - } - - @Override - public boolean isShowDoneButton() { - return mShowDoneButton; - } - - private void updateDoneButton() { - if (mDoneButton != null) { - mDoneButton.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE); - } - } - - @Override - public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) { - mDismissCallback = callback; - } - @Override public int getBaseline() { return mHourSpinner.getBaseline(); @@ -467,8 +409,7 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { @Override public Parcelable onSaveInstanceState(Parcelable superState) { - return new SavedState(superState, getCurrentHour(), getCurrentMinute(), - isShowDoneButton()); + return new SavedState(superState, getCurrentHour(), getCurrentMinute()); } @Override @@ -476,7 +417,6 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { SavedState ss = (SavedState) state; setCurrentHour(ss.getHour()); setCurrentMinute(ss.getMinute()); - setShowDoneButton(ss.isShowDoneButton()); } @Override @@ -632,25 +572,19 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { * Used to save / restore state of time picker */ private static class SavedState extends View.BaseSavedState { - private final int mHour; - private final int mMinute; - private final boolean mShowDoneButton; - - private SavedState(Parcelable superState, int hour, int minute, boolean showDoneButton) { + private SavedState(Parcelable superState, int hour, int minute) { super(superState); mHour = hour; mMinute = minute; - mShowDoneButton = showDoneButton; } private SavedState(Parcel in) { super(in); mHour = in.readInt(); mMinute = in.readInt(); - mShowDoneButton = (in.readInt() == 1); } public int getHour() { @@ -661,16 +595,11 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { return mMinute; } - public boolean isShowDoneButton() { - return mShowDoneButton; - } - @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mHour); dest.writeInt(mMinute); - dest.writeInt(mShowDoneButton ? 1 : 0); } @SuppressWarnings({"unused", "hiding"}) diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java index 523965c96e9e..9a50250587cf 100644 --- a/core/java/android/widget/TimePickerSpinnerDelegate.java +++ b/core/java/android/widget/TimePickerSpinnerDelegate.java @@ -43,7 +43,6 @@ import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.R; -import java.text.DateFormatSymbols; import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; @@ -86,8 +85,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im private RadialTimePickerView mRadialTimePickerView; private TextView mSeparatorView; - private ViewGroup mLayoutButtons; - private String mAmText; private String mPmText; @@ -101,16 +98,12 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im private String mDoublePlaceholderText; private String mDeletedKeyFormat; private boolean mInKbMode; + private boolean mIsTimeValid = true; private ArrayList mTypedTimes = new ArrayList(); private Node mLegalTimesTree; private int mAmKeyCode; private int mPmKeyCode; - // For showing the done button when in a Dialog - private Button mDoneButton; - private boolean mShowDoneButton; - private TimePicker.TimePickerDismissCallback mDismissCallback; - // Accessibility strings. private String mHourPickerDescription; private String mSelectHours; @@ -146,7 +139,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im mSeparatorView = (TextView) mainView.findViewById(R.id.separator); mMinuteView = (TextView) mainView.findViewById(R.id.minutes); mAmPmTextView = (TextView) mainView.findViewById(R.id.ampm_label); - mLayoutButtons = (ViewGroup) mainView.findViewById(R.id.layout_buttons); // Set up text appearances from style. final int headerTimeTextAppearance = a.getResourceId( @@ -174,7 +166,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im final int headerBackgroundColor = a.getColor( R.styleable.TimePicker_headerBackgroundColor, Color.TRANSPARENT); if (headerBackgroundColor != Color.TRANSPARENT) { - mLayoutButtons.setBackgroundColor(headerBackgroundColor); mainView.findViewById(R.id.time_header).setBackgroundColor(headerBackgroundColor); } @@ -182,7 +173,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im mRadialTimePickerView = (RadialTimePickerView) mainView.findViewById( R.id.radial_picker); - mDoneButton = (Button) mainView.findViewById(R.id.done_button); setupListeners(); @@ -199,16 +189,14 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im final Calendar calendar = Calendar.getInstance(mCurrentLocale); final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); final int currentMinute = calendar.get(Calendar.MINUTE); - initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX, false); + initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX); } - private void initialize(int hourOfDay, int minute, boolean is24HourView, int index, - boolean showDoneButton) { + private void initialize(int hourOfDay, int minute, boolean is24HourView, int index) { mInitialHourOfDay = hourOfDay; mInitialMinute = minute; mIs24HourView = is24HourView; mInKbMode = false; - mShowDoneButton = showDoneButton; updateUI(index); } @@ -236,21 +224,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im tryVibrate(); } }); - mDoneButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (mInKbMode && isTypedTimeFullyLegal()) { - finishKbMode(false); - } else { - tryVibrate(); - } - if (mDismissCallback != null) { - mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), - getCurrentMinute()); - } - } - }); - mDoneButton.setOnKeyListener(keyboardListener); } private void updateUI(int index) { @@ -258,8 +231,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im updateRadialPicker(index); // Enable or disable the AM/PM view. updateHeaderAmPm(); - // Show or hide Done button - updateDoneButton(); // Update Hour and Minutes updateHeaderHour(mInitialHourOfDay, true); // Update time separator @@ -336,10 +307,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im } } - private void updateDoneButton() { - mLayoutButtons.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE); - } - /** * Set the current hour. */ @@ -446,17 +413,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im return mIsEnabled; } - @Override - public void setShowDoneButton(boolean showDoneButton) { - mShowDoneButton = showDoneButton; - updateDoneButton(); - } - - @Override - public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) { - mDismissCallback = callback; - } - @Override public int getBaseline() { // does not support baseline alignment @@ -471,8 +427,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im @Override public Parcelable onSaveInstanceState(Parcelable superState) { return new SavedState(superState, getCurrentHour(), getCurrentMinute(), - is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing(), - isShowDoneButton()); + is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing()); } @Override @@ -480,8 +435,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im SavedState ss = (SavedState) state; setInKbMode(ss.inKbMode()); setTypedTimes(ss.getTypesTimes()); - initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing(), - ss.isShowDoneButton()); + initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing()); mRadialTimePickerView.invalidate(); if (mInKbMode) { tryStartingKbMode(-1); @@ -560,11 +514,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im return mRadialTimePickerView.getCurrentItemShowing(); } - @Override - public boolean isShowDoneButton() { - return mShowDoneButton; - } - /** * Propagate the time change */ @@ -587,11 +536,10 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im private final boolean mInKbMode; private final ArrayList mTypedTimes; private final int mCurrentItemShowing; - private final boolean mShowDoneButton; private SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode, boolean isKbMode, ArrayList typedTimes, - int currentItemShowing, boolean showDoneButton) { + int currentItemShowing) { super(superState); mHour = hour; mMinute = minute; @@ -599,7 +547,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im mInKbMode = isKbMode; mTypedTimes = typedTimes; mCurrentItemShowing = currentItemShowing; - mShowDoneButton = showDoneButton; } private SavedState(Parcel in) { @@ -610,7 +557,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im mInKbMode = (in.readInt() == 1); mTypedTimes = in.readArrayList(getClass().getClassLoader()); mCurrentItemShowing = in.readInt(); - mShowDoneButton = (in.readInt() == 1); } public int getHour() { @@ -637,10 +583,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im return mCurrentItemShowing; } - public boolean isShowDoneButton() { - return mShowDoneButton; - } - @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); @@ -650,7 +592,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im dest.writeInt(mInKbMode ? 1 : 0); dest.writeList(mTypedTimes); dest.writeInt(mCurrentItemShowing); - dest.writeInt(mShowDoneButton ? 1 : 0); } @SuppressWarnings({"unused", "hiding"}) @@ -852,12 +793,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im * @return true if the key was successfully processed, false otherwise. */ private boolean processKeyUp(int keyCode) { - if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_BACK) { - if (mDismissCallback != null) { - mDismissCallback.dismiss(mDelegator, true, getCurrentHour(), getCurrentMinute()); - } - return true; - } else if (keyCode == KeyEvent.KEYCODE_TAB) { + if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_TAB) { if(mInKbMode) { if (isTypedTimeFullyLegal()) { finishKbMode(true); @@ -876,9 +812,6 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im mRadialTimePickerView.getCurrentHour(), mRadialTimePickerView.getCurrentMinute()); } - if (mDismissCallback != null) { - mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), getCurrentMinute()); - } return true; } else if (keyCode == KeyEvent.KEYCODE_DEL) { if (mInKbMode) { @@ -933,7 +866,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im private void tryStartingKbMode(int keyCode) { if (keyCode == -1 || addKeyIfLegal(keyCode)) { mInKbMode = true; - mDoneButton.setEnabled(false); + onValidationChanged(false); updateDisplay(false); mRadialTimePickerView.setInputEnabled(false); } @@ -961,7 +894,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); } - mDoneButton.setEnabled(true); + onValidationChanged(true); } return true; @@ -1002,7 +935,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im private int deleteLastTypedKey() { int deleted = mTypedTimes.remove(mTypedTimes.size() - 1); if (!isTypedTimeFullyLegal()) { - mDoneButton.setEnabled(false); + onValidationChanged(false); } return deleted; } @@ -1046,7 +979,7 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im updateAmPmDisplay(hour < 12 ? AM : PM); } setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true, true); - mDoneButton.setEnabled(true); + onValidationChanged(true); } else { boolean[] enteredZeros = {false, false}; int[] values = getEnteredTime(enteredZeros); diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java index b67fa552752b..94c21dc5b9bc 100644 --- a/core/java/android/widget/YearPickerView.java +++ b/core/java/android/widget/YearPickerView.java @@ -45,7 +45,7 @@ class YearPickerView extends ListView implements AdapterView.OnItemClickListener } public YearPickerView(Context context, AttributeSet attrs) { - this(context, attrs, 0); + this(context, attrs, R.attr.listViewStyle); } public YearPickerView(Context context, AttributeSet attrs, int defStyleAttr) { diff --git a/core/res/res/layout-land/date_picker_holo.xml b/core/res/res/layout-land/date_picker_holo.xml index af8f59853462..9a9b8b0ec380 100644 --- a/core/res/res/layout-land/date_picker_holo.xml +++ b/core/res/res/layout-land/date_picker_holo.xml @@ -20,26 +20,11 @@ android:gravity="center" android:orientation="horizontal" > - - - - - - - - - - - + - \ No newline at end of file + diff --git a/core/res/res/layout-land/time_picker_holo.xml b/core/res/res/layout-land/time_picker_holo.xml index 1725ddc26365..3b3d63c0b14c 100644 --- a/core/res/res/layout-land/time_picker_holo.xml +++ b/core/res/res/layout-land/time_picker_holo.xml @@ -30,39 +30,18 @@ android:layout_width="@dimen/timepicker_left_side_width" android:layout_height="match_parent" android:orientation="vertical"> - - - - -