/** * 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; } // check if the spinner is init ok if (spinner.getChildCount() != PICKER_CHILD_COUNT) { Log.e(TAG, "spinner.getChildCount() != 3,It isn't init ok.return"); return; } // get the middle EditText of NumberPicker TextView input = (TextView) spinner.getChildAt(1); input.setImeOptions(imeOptions); }
private void setContentDescriptions() { Context context = getContext(); // check if the compponent is init ok if (mDaySpinner.getChildCount() != PICKER_CHILD_COUNT) { Log.e(TAG, "mDaySpinner.getChildCount() != 3,It isn't init ok.return"); return; } else if (mMonthSpinner.getChildCount() != PICKER_CHILD_COUNT) { Log.e(TAG, "mMonthSpinner.getChildCount() != 3,It isn't init ok.return"); return; } else if (mYearSpinner.getChildCount() != PICKER_CHILD_COUNT) { Log.e(TAG, "mYearSpinner.getChildCount() != 3,It isn't init ok.return"); return; } // Day String text = context.getString(R.string.date_picker_increment_day_button); // set the Top Button of NumberPicker ((ImageButton) mDaySpinner.getChildAt(0)).setContentDescription(text); text = context.getString(R.string.date_picker_decrement_day_button); // set the Bottom Button of NumberPicker ((ImageButton) mDaySpinner.getChildAt(2)).setContentDescription(text); // Month // set the Top Button of NumberPicker text = context.getString(R.string.date_picker_increment_month_button); ((ImageButton) mMonthSpinner.getChildAt(0)).setContentDescription(text); text = context.getString(R.string.date_picker_decrement_month_button); // set the Bottom Button of NumberPicker ((ImageButton) mMonthSpinner.getChildAt(2)).setContentDescription(text); // Year // set the Top Button of NumberPicker text = context.getString(R.string.date_picker_increment_year_button); ((ImageButton) mYearSpinner.getChildAt(0)).setContentDescription(text); // set the Bottom Button of NumberPicker text = context.getString(R.string.date_picker_decrement_year_button); ((ImageButton) mYearSpinner.getChildAt(2)).setContentDescription(text); }
public LunarDatePicker(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // initialization based on locale setCurrentLocale(Locale.getDefault()); // /@M:{comment these lines // TypedArray attributesArray = context.obtainStyledAttributes(attrs, // R.styleable.LunarDatePicker, // defStyle, 0); // boolean spinnersShown = // attributesArray.getBoolean(R.styleable.LunarDatePicker_spinnersShown, // DEFAULT_SPINNERS_SHOWN); // boolean calendarViewShown = attributesArray.getBoolean( // R.styleable.LunarDatePicker_calendarViewShown, // DEFAULT_CALENDAR_VIEW_SHOWN); // int startYear = // attributesArray.getInt(R.styleable.LunarDatePicker_startYear, // DEFAULT_START_YEAR); // int endYear = attributesArray.getInt(R.styleable.LunarDatePicker_endYear, // DEFAULT_END_YEAR); // String minDate = // attributesArray.getString(R.styleable.LunarDatePicker_minDate); // String maxDate = // attributesArray.getString(R.styleable.LunarDatePicker_maxDate); // int layoutResourceId =R.layout.date_picker; // attributesArray.getResourceId(R.styleable.LunarDatePicker_layout, // R.layout.date_picker); // attributesArray.recycle(); // /} // /M:add @{ boolean spinnersShown = DEFAULT_SPINNERS_SHOWN; boolean calendarViewShown = DEFAULT_CALENDAR_VIEW_SHOWN; int startYear = DEFAULT_START_YEAR; int endYear = DEFAULT_END_YEAR; int layoutResourceId = R.layout.date_picker; // /} LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(layoutResourceId, this, true); OnValueChangeListener onChangeListener = new OnValueChangeListener() { public void onValueChange(NumberPicker picker, int oldVal, int newVal) { updateInputState(); mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis()); int gregorianYear = mTempDate.get(Calendar.YEAR); int gregorianMonth = mTempDate.get(Calendar.MONTH) + 1; int gregorianDay = mTempDate.get(Calendar.DAY_OF_MONTH); int lunarDates[] = LunarUtil.calculateLunarByGregorian(gregorianYear, gregorianMonth, gregorianDay); // take care of wrapping of days and months to update greater // fields if (picker == mDaySpinner) { if (oldVal > 27 && newVal == 1) { mTempDate.add(Calendar.DAY_OF_MONTH, 1); } else if (oldVal == 1 && newVal > 27) { mTempDate.add(Calendar.DAY_OF_MONTH, -1); } else { mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal); } } else if (picker == mMonthSpinner) { int leapMonth = 0; int monthCountDays = 0; if (oldVal > 10 && newVal == 0) { leapMonth = LunarUtil.leapMonth(lunarDates[0]); if (leapMonth == 12) { monthCountDays = LunarUtil.daysOfLeapMonthInLunarYear(lunarDates[0]); } else { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], 12); } mTempDate.add(Calendar.DAY_OF_MONTH, monthCountDays); } else if (oldVal == 0 && newVal > 10) { leapMonth = LunarUtil.leapMonth(lunarDates[0] - 1); if (leapMonth == 12) { monthCountDays = LunarUtil.daysOfLeapMonthInLunarYear(lunarDates[0]); } else { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0] - 1, 12); } mTempDate.add(Calendar.DAY_OF_MONTH, -monthCountDays); } else { leapMonth = LunarUtil.leapMonth(lunarDates[0]); // move to previous if ((newVal - oldVal) < 0) { if (leapMonth == 0) { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], newVal + 1); } else { // leap year if (newVal < leapMonth) { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], newVal + 1); } else if (newVal == leapMonth) { monthCountDays = LunarUtil.daysOfLeapMonthInLunarYear(lunarDates[0]); } else { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], newVal); } } monthCountDays = -monthCountDays; } else { // move to next month if (leapMonth == 0) { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], oldVal + 1); } else { // leap year if (oldVal < leapMonth) { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], oldVal + 1); } else if (oldVal == leapMonth) { monthCountDays = LunarUtil.daysOfLeapMonthInLunarYear(lunarDates[0]); } else { monthCountDays = LunarUtil.daysOfALunarMonth(lunarDates[0], oldVal); } } } mTempDate.add(Calendar.DAY_OF_MONTH, monthCountDays); } } else if (picker == mYearSpinner) { int orientation = newVal - oldVal > 0 ? LunarUtil.INCREASE_A_LUANR_YEAR : LunarUtil.DECREATE_A_LUANR_YEAR; mTempDate = LunarUtil.decreaseOrIncreaseALunarYear( mTempDate, lunarDates[1], lunarDates[2], orientation); } else { throw new IllegalArgumentException(); } // now set the date to the adjusted one setDate( mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH), mTempDate.get(Calendar.DAY_OF_MONTH)); updateSpinners(); updateCalendarView(); notifyDateChanged(); } }; mSpinners = (LinearLayout) findViewById(R.id.pickers); // calendar view day-picker mCalendarView = (CalendarView) findViewById(R.id.calendar_view); mCalendarView.setOnDateChangeListener( new CalendarView.OnDateChangeListener() { public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) { setDate(year, month, monthDay); updateSpinners(); notifyDateChanged(); } }); // day mDaySpinner = (NumberPicker) findViewById(R.id.day); // /M: comment this line @{ // mDaySpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); // /} mDaySpinner.setOnLongPressUpdateInterval(100); mDaySpinner.setOnValueChangedListener(onChangeListener); // mDaySpinner has 3 child,topButton,editText,bottomButtom if (mDaySpinner.getChildCount() == PICKER_CHILD_COUNT) { // set the Middle EditText of Numberpicker read only. mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1); mDaySpinnerInput.setClickable(false); mDaySpinnerInput.setFocusable(false); } else { // Normally,this will always not happen. mDaySpinnerInput = new EditText(context); Log.e(TAG, "mDaySpinner.getChildCount() != 3,It isn't init ok."); } // month mMonthSpinner = (NumberPicker) findViewById(R.id.month); mMonthSpinner.setMinValue(0); mMonthSpinner.setMaxValue(mNumberOfMonths - 1); mMonthSpinner.setDisplayedValues(mShortMonths); mMonthSpinner.setOnLongPressUpdateInterval(200); mMonthSpinner.setOnValueChangedListener(onChangeListener); // mDaySpinner has 3 child,topButton,editText,bottomButtom if (mMonthSpinner.getChildCount() == PICKER_CHILD_COUNT) { // set the Middle EditText of Numberpicker read only. mMonthSpinnerInput = (EditText) mMonthSpinner.getChildAt(1); mMonthSpinnerInput.setClickable(false); mMonthSpinnerInput.setFocusable(false); } else { // Normally,this will always not happen. mMonthSpinnerInput = new EditText(context); Log.e(TAG, "mMonthSpinner.getChildCount() != 3,It isn't init ok."); } // year mYearSpinner = (NumberPicker) findViewById(R.id.year); mYearSpinner.setOnLongPressUpdateInterval(100); mYearSpinner.setOnValueChangedListener(onChangeListener); // mDaySpinner has 3 child,topButton,editText,bottomButtom if (mYearSpinner.getChildCount() == PICKER_CHILD_COUNT) { // set the Middle EditText of Numberpicker read only. mYearSpinnerInput = (EditText) mYearSpinner.getChildAt(1); mYearSpinnerInput.setClickable(false); mYearSpinnerInput.setFocusable(false); } else { // Normally,this will always not happen. mYearSpinnerInput = new EditText(context); Log.e(TAG, "mYearSpinner.getChildCount() != 3,It isn't init ok."); } // show only what the user required but make sure we // show something and the spinners have higher priority if (!spinnersShown && !calendarViewShown) { setSpinnersShown(true); } else { setSpinnersShown(spinnersShown); setCalendarViewShown(calendarViewShown); } // set the min date giving priority of the minDate over startYear mTempDate.clear(); mTempDate.set(startYear, 0, 1); setMinDate(mTempDate.getTimeInMillis()); // set the max date giving priority of the maxDate over endYear mTempDate.clear(); mTempDate.set(endYear, 11, 31); setMaxDate(mTempDate.getTimeInMillis()); // initialize to current date mCurrentDate.setTimeInMillis(System.currentTimeMillis()); init( mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate.get(Calendar.DAY_OF_MONTH), null); // re-order the number spinners to match the current date format reorderSpinners(); // set content descriptions AccessibilityManager accessibilityManager = (AccessibilityManager) context.getSystemService(context.ACCESSIBILITY_SERVICE); if (accessibilityManager.isEnabled()) { setContentDescriptions(); } }
public DateTimePicker( Context context, String dateFormat, String dateTimeValue, PickersState state, String minDateValue, String maxDateValue) { super(context); setCurrentLocale(Locale.getDefault()); mState = state; LayoutInflater inflater = LayoutInflater.from(context); inflater.inflate(R.layout.datetime_picker, this, true); mOnChangeListener = new OnValueChangeListener(); mDateSpinners = (LinearLayout) findViewById(R.id.date_spinners); mTimeSpinners = (LinearLayout) findViewById(R.id.time_spinners); mPickers = (LinearLayout) findViewById(R.id.datetime_picker); // We will display differently according to the screen size width. WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); DisplayMetrics dm = new DisplayMetrics(); display.getMetrics(dm); mScreenWidth = display.getWidth() / dm.densityDpi; mScreenHeight = display.getHeight() / dm.densityDpi; if (DEBUG) { Log.d(LOGTAG, "screen width: " + mScreenWidth + " screen height: " + mScreenHeight); } // Set the min / max attribute. try { if (minDateValue != null && !minDateValue.equals("")) { mMinDate.setTime(new SimpleDateFormat(dateFormat).parse(minDateValue)); } else { mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); } } catch (Exception ex) { Log.e(LOGTAG, "Error parsing format sting: " + ex); mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); } try { if (maxDateValue != null && !maxDateValue.equals("")) { mMaxDate.setTime(new SimpleDateFormat(dateFormat).parse(maxDateValue)); } else { mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); } } catch (Exception ex) { Log.e(LOGTAG, "Error parsing format string: " + ex); mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); } // Find the initial date from the constructor arguments. try { if (!dateTimeValue.equals("")) { mTempDate.setTime(new SimpleDateFormat(dateFormat).parse(dateTimeValue)); } else { mTempDate.setTimeInMillis(System.currentTimeMillis()); } } catch (Exception ex) { Log.e(LOGTAG, "Error parsing format string: " + ex); mTempDate.setTimeInMillis(System.currentTimeMillis()); } if (mMaxDate.before(mMinDate)) { // If the input date range is illogical/garbage, we should not restrict the input range (i.e. // allow the // user to select any date). If we try to make any assumptions based on the illogical min/max // date we could // potentially prevent the user from selecting dates that are in the developers intended // range, so it's best // to allow anything. mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); } // mTempDate will either be a site-supplied value, or today's date otherwise. CalendarView // implementations can // crash if they're supplied an invalid date (i.e. a date not in the specified range), hence we // need to set // a sensible default date here. if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) { mTempDate.setTimeInMillis(mMinDate.getTimeInMillis()); } // If we're displaying a date, the screen is wide enough // (and if we're using an SDK where the calendar view exists) // then display a calendar. if (Versions.feature11Plus && (mState == PickersState.DATE || mState == PickersState.DATETIME) && mScreenWidth >= SCREEN_SIZE_THRESHOLD) { if (DEBUG) { Log.d(LOGTAG, "SDK > 10 and screen wide enough, displaying calendar"); } mCalendar = new CalendarView(context); mCalendar.setVisibility(GONE); LayoutParams layoutParams = new LayoutParams(250, 280); mCalendar.setLayoutParams(layoutParams); mCalendar.setFocusable(true); mCalendar.setFocusableInTouchMode(true); mCalendar.setMaxDate(mMaxDate.getTimeInMillis()); mCalendar.setMinDate(mMinDate.getTimeInMillis()); mCalendar.setDate(mTempDate.getTimeInMillis(), false, false); mCalendar.setOnDateChangeListener( new CalendarView.OnDateChangeListener() { @Override public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) { mTempDate.set(year, month, monthDay); setDate(mTempDate); notifyDateChanged(); } }); mPickers.addView(mCalendar); } else { // If the screen is more wide than high, we are displaying day and // time spinners, and if there is no calendar displayed, we should // display the fields in one row. if (mScreenWidth > mScreenHeight && mState == PickersState.DATETIME) { mPickers.setOrientation(LinearLayout.HORIZONTAL); } mCalendar = null; } // Initialize all spinners. mDaySpinner = setupSpinner(R.id.day, 1, mTempDate.get(Calendar.DAY_OF_MONTH)); mDaySpinner.setFormatter(TWO_DIGIT_FORMATTER); mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1); mMonthSpinner = setupSpinner(R.id.month, 1, mTempDate.get(Calendar.MONTH) + 1); // Month is 0-based mMonthSpinner.setFormatter(TWO_DIGIT_FORMATTER); mMonthSpinner.setDisplayedValues(mShortMonths); mMonthSpinnerInput = (EditText) mMonthSpinner.getChildAt(1); mWeekSpinner = setupSpinner(R.id.week, 1, mTempDate.get(Calendar.WEEK_OF_YEAR)); mWeekSpinner.setFormatter(TWO_DIGIT_FORMATTER); mWeekSpinnerInput = (EditText) mWeekSpinner.getChildAt(1); mYearSpinner = setupSpinner(R.id.year, DEFAULT_START_YEAR, DEFAULT_END_YEAR); mYearSpinnerInput = (EditText) mYearSpinner.getChildAt(1); mAMPMSpinner = setupSpinner(R.id.ampm, 0, 1); mAMPMSpinner.setFormatter(TWO_DIGIT_FORMATTER); if (mIs12HourMode) { mHourSpinner = setupSpinner(R.id.hour, 1, 12); mAMPMSpinnerInput = (EditText) mAMPMSpinner.getChildAt(1); mAMPMSpinner.setDisplayedValues(mShortAMPMs); } else { mHourSpinner = setupSpinner(R.id.hour, 0, 23); mAMPMSpinnerInput = null; } mHourSpinner.setFormatter(TWO_DIGIT_FORMATTER); mHourSpinnerInput = (EditText) mHourSpinner.getChildAt(1); mMinuteSpinner = setupSpinner(R.id.minute, 0, 59); mMinuteSpinner.setFormatter(TWO_DIGIT_FORMATTER); mMinuteSpinnerInput = (EditText) mMinuteSpinner.getChildAt(1); // The order in which the spinners are displayed are locale-dependent reorderDateSpinners(); // Set the date to the initial date. Since this date can come from the user, // it can fire an exception (out-of-bound date) try { updateDate(mTempDate); } catch (Exception ex) { } // Display only the pickers needed for the current state. displayPickers(); }