mobile/android/base/widget/DateTimePicker.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2  * Copyright (C) 2007 The Android Open Source Project
     3  *
     4  * Licensed under the Apache License, Version 2.0 (the "License");
     5  * you may not use this file except in compliance with the License.
     6  * You may obtain a copy of the License at
     7  *
     8  *      http://www.apache.org/licenses/LICENSE-2.0
     9  *
    10  * Unless required by applicable law or agreed to in writing, software
    11  * distributed under the License is distributed on an "AS IS" BASIS,
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  * See the License for the specific language governing permissions and
    14  * limitations under the License.
    15  */
    17 package org.mozilla.gecko.widget;
    19 import org.mozilla.gecko.R;
    21 import android.content.Context;
    22 import android.os.Build;
    23 import android.text.format.DateFormat;
    24 import android.text.format.DateUtils;
    25 import android.util.DisplayMetrics;
    26 import android.util.Log;
    27 import android.view.Display;
    28 import android.view.LayoutInflater;
    29 import android.view.WindowManager;
    30 import android.view.accessibility.AccessibilityEvent;
    31 import android.view.inputmethod.InputMethodManager;
    32 import android.widget.CalendarView;
    33 import android.widget.EditText;
    34 import android.widget.FrameLayout;
    35 import android.widget.LinearLayout;
    36 import android.widget.NumberPicker;
    38 import java.text.SimpleDateFormat;
    39 import java.util.Arrays;
    40 import java.util.Calendar;
    41 import java.util.Locale;
    43 public class DateTimePicker extends FrameLayout {
    45     private static final boolean DEBUG = true;
    46     private static final String LOGTAG = "GeckoDateTimePicker";
    47     private static final String DATE_FORMAT = "MM/dd/yyyy";
    48     private static final int DEFAULT_START_YEAR = 1;
    49     private static final int DEFAULT_END_YEAR = 9999;
    50     // Minimal screen width (in inches) for which we can show the calendar;
    51     private static final int SCREEN_SIZE_THRESHOLD = 5;
    52     private boolean mYearEnabled = true;
    53     private boolean mMonthEnabled = true;
    54     private boolean mWeekEnabled = false;
    55     private boolean mDayEnabled = true;
    56     private boolean mHourEnabled = true;
    57     private boolean mMinuteEnabled = true;
    58     private boolean mCalendarEnabled = false;
    59     private boolean mIs12HourMode;
    60     // Size of the screen in inches;
    61     private int mScreenWidth;
    62     private int mScreenHeight;
    63     private OnValueChangeListener mOnChangeListener;
    64     private final LinearLayout mPickers;
    65     private final LinearLayout mDateSpinners;
    66     private final LinearLayout mTimeSpinners;
    67     private final LinearLayout mSpinners;
    68     private final NumberPicker mDaySpinner;
    69     private final NumberPicker mMonthSpinner;
    70     private final NumberPicker mWeekSpinner;
    71     private final NumberPicker mYearSpinner;
    72     private final NumberPicker mHourSpinner;
    73     private final NumberPicker mMinuteSpinner;
    74     private final NumberPicker mAMPMSpinner;
    75     private final CalendarView mCalendar;
    76     private final EditText mDaySpinnerInput;
    77     private final EditText mMonthSpinnerInput;
    78     private final EditText mWeekSpinnerInput;
    79     private final EditText mYearSpinnerInput;
    80     private final EditText mHourSpinnerInput;
    81     private final EditText mMinuteSpinnerInput;
    82     private final EditText mAMPMSpinnerInput;
    83     private Locale mCurrentLocale;
    84     private String[] mShortMonths;
    85     private String[] mShortAMPMs;
    86     private int mNumberOfMonths;
    87     private Calendar mTempDate;
    88     private Calendar mMinDate;
    89     private Calendar mMaxDate;
    90     private Calendar mCurrentDate;
    91     private PickersState mState;
    93     public static enum PickersState { DATE, MONTH, WEEK, TIME, DATETIME };
    95     public class OnValueChangeListener implements NumberPicker.OnValueChangeListener {
    96         @Override
    97         public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
    98             updateInputState();
    99             mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
   100             boolean newBehavior = (Build.VERSION.SDK_INT > 10);
   101             if (newBehavior) {
   102                 if (DEBUG) Log.d(LOGTAG, "Sdk version > 10, using new behavior");
   103                 //The native date picker widget on these sdks increment
   104                 //the next field when one field reach the maximum
   105                 if (picker == mDaySpinner && mDayEnabled) {
   106                     int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
   107                     int old = mTempDate.get(Calendar.DAY_OF_MONTH);
   108                     setTempDate(Calendar.DAY_OF_MONTH, old, newVal, 1, maxDayOfMonth);
   109                 } else if (picker == mMonthSpinner && mMonthEnabled) {
   110                     int old = mTempDate.get(Calendar.MONTH);
   111                     setTempDate(Calendar.MONTH, old, newVal, Calendar.JANUARY, Calendar.DECEMBER);
   112                 } else if (picker == mWeekSpinner) {
   113                     int old = mTempDate.get(Calendar.WEEK_OF_YEAR);
   114                     int maxWeekOfYear = mTempDate.getActualMaximum(Calendar.WEEK_OF_YEAR);
   115                     setTempDate(Calendar.WEEK_OF_YEAR, old, newVal, 0, maxWeekOfYear);
   116                 } else if (picker == mYearSpinner && mYearEnabled) {
   117                     int month = mTempDate.get(Calendar.MONTH);
   118                     mTempDate.set(Calendar.YEAR,newVal);
   119                     // Changing the year shouldn't change the month. (in case of non-leap year a Feb 29)
   120                     // change the day instead;
   121                     if (month != mTempDate.get(Calendar.MONTH)){
   122                         mTempDate.set(Calendar.MONTH, month);
   123                         mTempDate.set(Calendar.DAY_OF_MONTH,
   124                         mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
   125                     }
   126                 } else if (picker == mHourSpinner && mHourEnabled) {
   127                     if (mIs12HourMode) {
   128                         setTempDate(Calendar.HOUR, oldVal, newVal, 1, 12);
   129                     } else {
   130                         setTempDate(Calendar.HOUR_OF_DAY, oldVal, newVal, 0, 23);
   131                     }
   132                 } else if (picker == mMinuteSpinner && mMinuteEnabled) {
   133                     setTempDate(Calendar.MINUTE, oldVal, newVal, 0, 59);
   134                 } else if (picker == mAMPMSpinner && mHourEnabled) {
   135                     mTempDate.set(Calendar.AM_PM,newVal);
   136                 } else {
   137                     throw new IllegalArgumentException();
   138                 }
   139             } else {
   140                 if (DEBUG) Log.d(LOGTAG,"Sdk version < 10, using old behavior");
   141                 if (picker == mDaySpinner && mDayEnabled){
   142                     mTempDate.set(Calendar.DAY_OF_MONTH, newVal);
   143                 } else if (picker == mMonthSpinner && mMonthEnabled){
   144                     mTempDate.set(Calendar.MONTH, newVal);
   145                     if (mTempDate.get(Calendar.MONTH) == newVal+1){
   146                         mTempDate.set(Calendar.MONTH, newVal);
   147                         mTempDate.set(Calendar.DAY_OF_MONTH,
   148                         mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
   149                     }
   150                 } else if (picker == mWeekSpinner){
   151                     mTempDate.set(Calendar.WEEK_OF_YEAR, newVal);
   152                 } else if (picker == mYearSpinner && mYearEnabled){
   153                     int month = mTempDate.get(Calendar.MONTH);
   154                     mTempDate.set(Calendar.YEAR, newVal);
   155                     if (month != mTempDate.get(Calendar.MONTH)) {
   156                         mTempDate.set(Calendar.MONTH, month);
   157                         mTempDate.set(Calendar.DAY_OF_MONTH,
   158                         mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
   159                     }
   160                 } else if (picker == mHourSpinner && mHourEnabled){
   161                     if (mIs12HourMode) {
   162                         mTempDate.set(Calendar.HOUR, newVal);
   163                     } else {
   164                         mTempDate.set(Calendar.HOUR_OF_DAY, newVal);
   165                     }
   166                 } else if (picker == mMinuteSpinner && mMinuteEnabled){
   167                     mTempDate.set(Calendar.MINUTE, newVal);
   168                 } else if (picker == mAMPMSpinner && mHourEnabled) {
   169                     mTempDate.set(Calendar.AM_PM, newVal);
   170                 } else {
   171                     throw new IllegalArgumentException();
   172                 }
   173             }
   174             setDate(mTempDate);
   175             if (mDayEnabled) {
   176                 mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
   177             }
   178             if(mWeekEnabled) {
   179                 mWeekSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.WEEK_OF_YEAR));
   180             }
   181             updateCalendar();
   182             updateSpinners();
   183             notifyDateChanged();
   184         }
   186         private void setTempDate(int field, int oldVal, int newVal, int min, int max) {
   187             if (oldVal == max && newVal == min ) {
   188                 mTempDate.add(field, 1);
   189             } else if (oldVal == min && newVal == max) {
   190                 mTempDate.add(field, -1);
   191             } else {
   192                 mTempDate.add(field, newVal - oldVal);
   193             }
   194         }
   195     }
   197     private static final NumberPicker.Formatter TWO_DIGIT_FORMATTER = new NumberPicker.Formatter() {
   198         final StringBuilder mBuilder = new StringBuilder();
   200         final java.util.Formatter mFmt = new java.util.Formatter(mBuilder, java.util.Locale.US);
   202         final Object[] mArgs = new Object[1];
   204         @Override
   205         public String format(int value) {
   206             mArgs[0] = value;
   207             mBuilder.delete(0, mBuilder.length());
   208             mFmt.format("%02d", mArgs);
   209             return mFmt.toString();
   210         }
   211     };
   213     private void displayPickers() {
   214         setWeekShown(false);
   215         set12HourShown(mIs12HourMode);
   216         if (mState == PickersState.DATETIME) {
   217             return;
   218         }
   219         setHourShown(false);
   220         setMinuteShown(false);
   221         if (mState == PickersState.WEEK) {
   222             setDayShown(false);
   223             setMonthShown(false);
   224             setWeekShown(true);
   225         } else if (mState == PickersState.MONTH) {
   226             setDayShown(false);
   227         }
   228     }
   230     public DateTimePicker(Context context) {
   231         this(context, "", "", PickersState.DATE);
   232     }
   234     public DateTimePicker(Context context, String dateFormat, String dateTimeValue, PickersState state) {
   235         super(context);
   236         if (Build.VERSION.SDK_INT < 11) {
   237             throw new UnsupportedOperationException("Custom DateTimePicker is only available for SDK > 10");
   238         }
   239         setCurrentLocale(Locale.getDefault());
   240         mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
   241         mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
   242         mState = state;
   243         LayoutInflater inflater = LayoutInflater.from(context);
   244         inflater.inflate(R.layout.datetime_picker, this, true);
   246         mOnChangeListener = new OnValueChangeListener();
   248         mDateSpinners = (LinearLayout)findViewById(R.id.date_spinners);
   249         mTimeSpinners = (LinearLayout)findViewById(R.id.time_spinners);
   250         mSpinners = (LinearLayout)findViewById(R.id.spinners);
   251         mPickers = (LinearLayout)findViewById(R.id.datetime_picker);
   253         // We will display differently according to the screen size width.
   254         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
   255         Display display = wm.getDefaultDisplay();
   256         DisplayMetrics dm = new DisplayMetrics();
   257         display.getMetrics(dm);
   258         mScreenWidth = display.getWidth() / dm.densityDpi;
   259         mScreenHeight = display.getHeight() / dm.densityDpi;
   260         if (DEBUG) Log.d(LOGTAG, "screen width: " + mScreenWidth + " screen height: " + mScreenHeight);
   262         // If we're displaying a date, the screen is wide enought (and if we're using a sdk where the calendar view exists)
   263         // then display a calendar.
   264         if ((mState == PickersState.DATE || mState == PickersState.DATETIME) &&
   265             Build.VERSION.SDK_INT > 10 && mScreenWidth >= SCREEN_SIZE_THRESHOLD) {
   266             if (DEBUG) Log.d(LOGTAG,"SDK > 10 and screen wide enough, displaying calendar");
   267             mCalendar = new CalendarView(context);
   268             mCalendar.setVisibility(GONE);
   270             LayoutParams layoutParams = new LayoutParams(250,280);
   271             mCalendar.setLayoutParams(layoutParams);
   272             mCalendar.setFocusable(true);
   273             mCalendar.setFocusableInTouchMode(true);
   274             mCalendar.setMaxDate(mMaxDate.getTimeInMillis());
   275             mCalendar.setMinDate(mMinDate.getTimeInMillis());
   277             mCalendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
   278                 @Override
   279                 public void onSelectedDayChange(
   280                     CalendarView view, int year, int month, int monthDay) {
   281                     mTempDate.set(year, month, monthDay);
   282                     setDate(mTempDate);
   283                     notifyDateChanged();
   284                 }
   285             });
   287             mPickers.addView(mCalendar);
   288         } else {
   289           // If the screen is more wide than high, we are displaying daye and time spinners,
   290           // and if there is no calendar displayed,
   291           // we should display the fields in one row.
   292             if (mScreenWidth > mScreenHeight && mState == PickersState.DATETIME) {
   293                 mSpinners.setOrientation(LinearLayout.HORIZONTAL);
   294             }
   295             mCalendar = null;
   296         }
   298         // Find the initial date from the constructor arguments.
   299         try {
   300             if (!dateTimeValue.equals("")) {
   301                 mTempDate.setTime(new SimpleDateFormat(dateFormat).parse(dateTimeValue));
   302             } else {
   303                 mTempDate.setTimeInMillis(System.currentTimeMillis());
   304             }
   305         } catch (Exception ex) {
   306             Log.e(LOGTAG, "Error parsing format string: " + ex);
   307             mTempDate.setTimeInMillis(System.currentTimeMillis());
   308         }
   310         // Initialize all spinners.
   311         mDaySpinner = setupSpinner(R.id.day, 1,
   312                                    mTempDate.get(Calendar.DAY_OF_MONTH));
   313         mDaySpinner.setFormatter(TWO_DIGIT_FORMATTER);
   314         mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1);
   316         mMonthSpinner = setupSpinner(R.id.month, 1,
   317                                      mTempDate.get(Calendar.MONTH));
   318         mMonthSpinner.setFormatter(TWO_DIGIT_FORMATTER);
   319         mMonthSpinner.setDisplayedValues(mShortMonths);
   320         mMonthSpinnerInput = (EditText) mMonthSpinner.getChildAt(1);
   322         mWeekSpinner = setupSpinner(R.id.week, 1,
   323                                     mTempDate.get(Calendar.WEEK_OF_YEAR));
   324         mWeekSpinner.setFormatter(TWO_DIGIT_FORMATTER);
   325         mWeekSpinnerInput = (EditText) mWeekSpinner.getChildAt(1);
   327         mYearSpinner = setupSpinner(R.id.year, DEFAULT_START_YEAR,
   328                                     DEFAULT_END_YEAR);
   329         mYearSpinnerInput = (EditText) mYearSpinner.getChildAt(1);
   331         mAMPMSpinner = setupSpinner(R.id.ampm, 0, 1);
   332         mAMPMSpinner.setFormatter(TWO_DIGIT_FORMATTER);
   334         if (mIs12HourMode) {
   335             mHourSpinner = setupSpinner(R.id.hour, 1, 12);
   336             mAMPMSpinnerInput = (EditText) mAMPMSpinner.getChildAt(1);
   337             mAMPMSpinner.setDisplayedValues(mShortAMPMs); 
   338         } else {
   339             mHourSpinner = setupSpinner(R.id.hour, 0, 23);
   340             mAMPMSpinnerInput = null;
   341         }
   343         mHourSpinner.setFormatter(TWO_DIGIT_FORMATTER);
   344         mHourSpinnerInput = (EditText) mHourSpinner.getChildAt(1);
   346         mMinuteSpinner = setupSpinner(R.id.minute, 0, 59);
   347         mMinuteSpinner.setFormatter(TWO_DIGIT_FORMATTER);
   348         mMinuteSpinnerInput = (EditText) mMinuteSpinner.getChildAt(1);
   350         // The order in which the spinners are displayed are locale-dependent
   351         reorderDateSpinners();
   352         // Set the date to the initial date. Since this date can come from the user,
   353         // it can fire an exception (out-of-bound date)
   354         try {
   355           updateDate(mTempDate);
   356         } catch (Exception ex) { }
   358         // Display only the pickers needed for the current state.
   359         displayPickers();
   360     }
   362     public NumberPicker setupSpinner(int id, int min, int max) {
   363         NumberPicker mSpinner = (NumberPicker) findViewById(id);
   364         mSpinner.setMinValue(min);
   365         mSpinner.setMaxValue(max);
   366         mSpinner.setOnValueChangedListener(mOnChangeListener);
   367         mSpinner.setOnLongPressUpdateInterval(100);
   368         return mSpinner;
   369     }
   371     public long getTimeInMillis(){
   372         return mCurrentDate.getTimeInMillis();
   373     }
   375     private void reorderDateSpinners() {
   376         mDateSpinners.removeAllViews();
   377         char[] order = DateFormat.getDateFormatOrder(getContext());
   378         final int spinnerCount = order.length;
   379         for (int i = 0; i < spinnerCount; i++) {
   380             switch (order[i]) {
   381                 case DateFormat.DATE:
   382                     mDateSpinners.addView(mDaySpinner);
   383                     break;
   384                 case DateFormat.MONTH:
   385                     mDateSpinners.addView(mMonthSpinner);
   386                     break;
   387                 case DateFormat.YEAR:
   388                     mDateSpinners.addView(mYearSpinner);
   389                     break;
   390                 default:
   391                     throw new IllegalArgumentException();
   392             }
   393         }
   394         mDateSpinners.addView(mWeekSpinner);
   395     }
   397     private void setDate(Calendar calendar){
   398         mCurrentDate = mTempDate;
   399         if (mCurrentDate.before(mMinDate)) {
   400             mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
   401         } else if (mCurrentDate.after(mMaxDate)) {
   402             mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
   403         }
   404     }
   406     private void updateInputState() {
   407         InputMethodManager inputMethodManager = (InputMethodManager)
   408           getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
   409         if (mYearEnabled && inputMethodManager.isActive(mYearSpinnerInput)) {
   410             mYearSpinnerInput.clearFocus();
   411             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
   412         } else if (mMonthEnabled && inputMethodManager.isActive(mMonthSpinnerInput)) {
   413             mMonthSpinnerInput.clearFocus();
   414             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
   415         } else if (mDayEnabled && inputMethodManager.isActive(mDaySpinnerInput)) {
   416             mDaySpinnerInput.clearFocus();
   417             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
   418         } else if (mHourEnabled && inputMethodManager.isActive(mHourSpinnerInput)) {
   419             mHourSpinnerInput.clearFocus();
   420             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
   421         } else if (mMinuteEnabled && inputMethodManager.isActive(mMinuteSpinnerInput)) {
   422             mMinuteSpinnerInput.clearFocus();
   423             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
   424         }
   425     }
   427     private void updateSpinners() {
   428         if (mDayEnabled) {
   429             if (mCurrentDate.equals(mMinDate)) {
   430                 mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
   431                 mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
   432             } else if (mCurrentDate.equals(mMaxDate)) {
   433                 mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
   434                 mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
   435             } else {
   436                 mDaySpinner.setMinValue(1);
   437                 mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
   438             }
   439             mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
   440         }
   442         if (mWeekEnabled) {
   443             mWeekSpinner.setMinValue(1);
   444             mWeekSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.WEEK_OF_YEAR));
   445             mWeekSpinner.setValue(mCurrentDate.get(Calendar.WEEK_OF_YEAR));
   446         }
   448         if (mMonthEnabled) {
   449             mMonthSpinner.setDisplayedValues(null);
   450             if (mCurrentDate.equals(mMinDate)) {
   451                 mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
   452                 mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
   453             } else if (mCurrentDate.equals(mMaxDate)) {
   454                 mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
   455                 mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
   456             } else {
   457                 mMonthSpinner.setMinValue(Calendar.JANUARY);
   458                 mMonthSpinner.setMaxValue(Calendar.DECEMBER);
   459             }
   461             String[] displayedValues = Arrays.copyOfRange(mShortMonths,
   462                     mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
   463             mMonthSpinner.setDisplayedValues(displayedValues);
   464             mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
   465         }
   467         if (mYearEnabled) {
   468             mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
   469             mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
   470             mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
   471         }
   473         if (mHourEnabled) {
   474             if (mIs12HourMode) {
   475                 mHourSpinner.setValue(mCurrentDate.get(Calendar.HOUR));
   476                 mAMPMSpinner.setValue(mCurrentDate.get(Calendar.AM_PM));
   477                 mAMPMSpinner.setDisplayedValues(mShortAMPMs);
   478             } else {
   479                 mHourSpinner.setValue(mCurrentDate.get(Calendar.HOUR_OF_DAY));
   480             }
   481         }
   482         if (mMinuteEnabled) {
   483             mMinuteSpinner.setValue(mCurrentDate.get(Calendar.MINUTE));
   484         }
   485     }
   487     private void updateCalendar() {
   488         if (mCalendarEnabled){
   489             mCalendar.setDate(mCurrentDate.getTimeInMillis(), false, false);
   490         }
   491     }
   493     private void notifyDateChanged() {
   494         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
   495     }
   497     public void toggleCalendar(boolean shown) {
   498         if ((mState != PickersState.DATE && mState != PickersState.DATETIME) ||
   499             Build.VERSION.SDK_INT < 11 || mScreenWidth < SCREEN_SIZE_THRESHOLD) {
   500             if (DEBUG) Log.d(LOGTAG,"Cannot display calendar on this device, in this state" +
   501                 ": screen width :"+mScreenWidth);
   502             return;
   503         }
   504         if (shown){
   505             mCalendarEnabled = true;
   506             mCalendar.setVisibility(VISIBLE);
   507             setYearShown(false);
   508             setWeekShown(false);
   509             setMonthShown(false);
   510             setDayShown(false);
   511         } else {
   512             mCalendar.setVisibility(GONE);
   513             setYearShown(true);
   514             setMonthShown(true);
   515             setDayShown(true);
   516             mSpinners.setOrientation(LinearLayout.HORIZONTAL);
   517             mCalendarEnabled = false;
   518         }
   519     }
   521     private void setYearShown(boolean shown) {
   522         if (shown) {
   523             toggleCalendar(false);
   524             mYearSpinner.setVisibility(VISIBLE);
   525             mYearEnabled = true;
   526         } else {
   527             mYearSpinner.setVisibility(GONE);
   528             mYearEnabled = false;
   529         }
   530     }
   532     private void setWeekShown(boolean shown) {
   533         if (shown) {
   534             toggleCalendar(false);
   535             mWeekSpinner.setVisibility(VISIBLE);
   536             mWeekEnabled = true;
   537         } else {
   538             mWeekSpinner.setVisibility(GONE);
   539             mWeekEnabled = false;
   540         }
   541     }
   543     private void setMonthShown(boolean shown) {
   544         if (shown) {
   545             toggleCalendar(false);
   546             mMonthSpinner.setVisibility(VISIBLE);
   547             mMonthEnabled = true;
   548         } else {
   549             mMonthSpinner.setVisibility(GONE);
   550             mMonthEnabled = false;
   551         }
   552     }
   554     private void setDayShown(boolean shown) {
   555         if (shown) {
   556             toggleCalendar(false);
   557             mDaySpinner.setVisibility(VISIBLE);
   558             mDayEnabled = true;
   559         } else {
   560             mDaySpinner.setVisibility(GONE);
   561             mDayEnabled = false;
   562         }
   563     }
   565     private void set12HourShown(boolean shown) {
   566         if (shown) {
   567             mAMPMSpinner.setVisibility(VISIBLE);
   568         } else {
   569             mAMPMSpinner.setVisibility(GONE);
   570         }
   571     }
   573     private void setHourShown(boolean shown) {
   574         if (shown) {
   575             mHourSpinner.setVisibility(VISIBLE);
   576             mHourEnabled= true;
   577         } else {
   578             mHourSpinner.setVisibility(GONE);
   579             mAMPMSpinner.setVisibility(GONE);
   580             mTimeSpinners.setVisibility(GONE);
   581             mHourEnabled = false;
   582         }
   583     }
   585     private void setMinuteShown(boolean shown) {
   586         if (shown) {
   587             mMinuteSpinner.setVisibility(VISIBLE);
   588             mTimeSpinners.findViewById(R.id.mincolon).setVisibility(VISIBLE);
   589             mMinuteEnabled= true;
   590         } else {
   591             mMinuteSpinner.setVisibility(GONE);
   592             mTimeSpinners.findViewById(R.id.mincolon).setVisibility(GONE);
   593             mMinuteEnabled = false;
   594         }
   595     }
   597     private void setCurrentLocale(Locale locale) {
   598         if (locale.equals(mCurrentLocale)) {
   599             return;
   600         }
   602         mCurrentLocale = locale;
   603         mIs12HourMode = !DateFormat.is24HourFormat(getContext());
   604         mTempDate = getCalendarForLocale(mTempDate, locale);
   605         mMinDate = getCalendarForLocale(mMinDate, locale);
   606         mMaxDate = getCalendarForLocale(mMaxDate, locale);
   607         mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
   609         mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
   611         mShortAMPMs = new String[2];
   612         mShortAMPMs[0] = DateUtils.getAMPMString(Calendar.AM);
   613         mShortAMPMs[1] = DateUtils.getAMPMString(Calendar.PM);
   615         mShortMonths = new String[mNumberOfMonths];
   616         for (int i = 0; i < mNumberOfMonths; i++) {
   617             mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
   618                     DateUtils.LENGTH_MEDIUM);
   619         }
   620     }
   622     private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
   623         if (oldCalendar == null) {
   624             return Calendar.getInstance(locale);
   625         } else {
   626             final long currentTimeMillis = oldCalendar.getTimeInMillis();
   627             Calendar newCalendar = Calendar.getInstance(locale);
   628             newCalendar.setTimeInMillis(currentTimeMillis);
   629             return newCalendar;
   630         }
   631     }
   633     public void updateDate(Calendar calendar) {
   634         if (mCurrentDate.equals(calendar)) {
   635             return;
   636         }
   637         mCurrentDate.setTimeInMillis(calendar.getTimeInMillis());
   638         if (mCurrentDate.before(mMinDate)) {
   639             mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
   640         } else if (mCurrentDate.after(mMaxDate)) {
   641             mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
   642         }
   643         updateSpinners();
   644         notifyDateChanged();
   645     }
   647 }

mercurial