Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java

Issue 15057004: Week picker for android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed min/max bug Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java b/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java
new file mode 100644
index 0000000000000000000000000000000000000000..0612789427172c14cf45a8612f887840e89abb1a
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java
@@ -0,0 +1,237 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.widget.NumberPicker;
+import android.widget.NumberPicker.OnValueChangeListener;
+import android.text.format.DateUtils;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.FrameLayout;
+import android.widget.NumberPicker;
+
+import java.util.Calendar;
+
+import org.chromium.content.R;
+
+// This class is heavily based on android.widget.DatePicker.
+public abstract class TwoFieldDatePicker extends FrameLayout {
+
+ private NumberPicker mPositionInYearSpinner;
+
+ private NumberPicker mYearSpinner;
+
+ private OnMonthOrWeekChangedListener mMonthOrWeekChangedListener;
+
+ // It'd be nice to use android.text.Time like in other Dialogs but
+ // it suffers from the 2038 effect so it would prevent us from
+ // having dates over 2038.
+ private Calendar mMinDate;
+
+ private Calendar mMaxDate;
+
+ private Calendar mCurrentDate;
+
+ /**
+ * The callback used to indicate the user changes\d the date.
+ */
+ public interface OnMonthOrWeekChangedListener {
+
+ /**
+ * Called upon a date change.
+ *
+ * @param view The view associated with this listener.
+ * @param year The year that was set.
+ * @param positionInYear The month or week in year.
+ */
+ void onMonthOrWeekChanged(TwoFieldDatePicker view, int year, int positionInYear);
+ }
+
+ public TwoFieldDatePicker(Context context, long minValue, long maxValue) {
+ super(context, null, android.R.attr.datePickerStyle);
+
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.two_field_date_picker, this, true);
+
+ OnValueChangeListener onChangeListener = new OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ int year = getYear();
+ int positionInYear = getPositionInYear();
+ // take care of wrapping of days and months to update greater fields
+ if (picker == mPositionInYearSpinner) {
+ positionInYear = newVal;
+ if (oldVal == picker.getMaxValue() && newVal == picker.getMinValue()) {
+ year += 1;
+ } else if (oldVal == picker.getMinValue() && newVal == picker.getMaxValue()) {
+ year -=1;
+ }
+ } else if (picker == mYearSpinner) {
+ year = newVal;
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ // now set the date to the adjusted one
+ setCurrentDate(year, positionInYear);
+ updateSpinners();
+ notifyDateChanged();
+ }
+ };
+
+ mCurrentDate = Calendar.getInstance();
+ mMinDate = createDateFromValue(minValue);
+ mMaxDate = createDateFromValue(maxValue);
+
+ // month
+ mPositionInYearSpinner = (NumberPicker) findViewById(R.id.position_in_year);
+ mPositionInYearSpinner.setOnLongPressUpdateInterval(200);
+ mPositionInYearSpinner.setOnValueChangedListener(onChangeListener);
+
+ // year
+ mYearSpinner = (NumberPicker) findViewById(R.id.year);
+ mYearSpinner.setOnLongPressUpdateInterval(100);
+ mYearSpinner.setOnValueChangedListener(onChangeListener);
+ }
+
+ /**
+ * Initialize the state. If the provided values designate an inconsistent
+ * date the values are normalized before updating the spinners.
+ *
+ * @param year The initial year.
+ * @param positionInYear The initial month <strong>starting from zero</strong> or week in year.
+ * @param onMonthChangedListener How user is notified date is changed by
+ * user, can be null.
+ */
+ public void init(int year, int positionInYear,
+ OnMonthOrWeekChangedListener onMonthOrWeekChangedListener) {
+ setCurrentDate(year, positionInYear);
+ updateSpinners();
+ mMonthOrWeekChangedListener = onMonthOrWeekChangedListener;
+ }
+
+ public boolean isNewDate(int year, int positionInYear) {
+ return (getYear() != year || getPositionInYear() != positionInYear);
+ }
+
+ /**
+ * Subclasses know the semantics of @value, and need to return
+ * a Calendar corresponding to it.
+ */
+ protected abstract Calendar createDateFromValue(long value);
+
+ /**
+ * Updates the current date.
+ *
+ * @param year The year.
+ * @param positionInYear The month or week in year.
+ */
+ public void updateDate(int year, int positionInYear) {
+ if (!isNewDate(year, positionInYear)) {
+ return;
+ }
+ setCurrentDate(year, positionInYear);
+ updateSpinners();
+ notifyDateChanged();
+ }
+
+ /**
+ * Subclasses know the semantics of @positionInYear, and need to update @mCurrentDate to the
+ * appropriate date.
+ */
+ protected abstract void setCurrentDate(int year, int positionInYear);
+
+ protected void setCurrentDate(Calendar date) {
+ mCurrentDate = date;
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ onPopulateAccessibilityEvent(event);
+ return true;
+ }
+
+ @Override
+ public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+ super.onPopulateAccessibilityEvent(event);
+
+ final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
+ String selectedDateUtterance = DateUtils.formatDateTime(getContext(),
+ mCurrentDate.getTimeInMillis(), flags);
+ event.getText().add(selectedDateUtterance);
+ }
+
+ /**
+ * @return The selected year.
+ */
+ public int getYear() {
+ return mCurrentDate.get(Calendar.YEAR);
+ }
+
+ /**
+ * @return The selected month or week.
+ */
+ public abstract int getPositionInYear();
+
+ protected abstract int getMaxYear();
+
+ protected abstract int getMinYear();
+
+ protected abstract int getMaxPositionInYear();
+
+ protected abstract int getMinPositionInYear();
+
+ protected Calendar getMaxDate() {
+ return mMaxDate;
+ }
+
+ protected Calendar getMinDate() {
+ return mMinDate;
+ }
+
+ protected Calendar getCurrentDate() {
+ return mCurrentDate;
+ }
+
+ protected NumberPicker getPositionInYearSpinner() {
+ return mPositionInYearSpinner;
+ }
+
+ protected NumberPicker getYearSpinner() {
+ return mYearSpinner;
+ }
+
+ /**
+ * This method should be subclassed to update the spinners based on mCurrentDate.
+ */
+ protected void updateSpinners() {
+ // set the spinner ranges respecting the min and max dates
+ mPositionInYearSpinner.setMinValue(getMinPositionInYear());
+ mPositionInYearSpinner.setMaxValue(getMaxPositionInYear());
+ mPositionInYearSpinner.setWrapSelectorWheel(
+ !mCurrentDate.equals(mMinDate) && !mCurrentDate.equals(mMaxDate));
+
+ // year spinner range does not change based on the current date
+ mYearSpinner.setMinValue(getMinYear());
+ mYearSpinner.setMaxValue(getMaxYear());
+ mYearSpinner.setWrapSelectorWheel(false);
+
+ // set the spinner values
+ mYearSpinner.setValue(getYear());
+ mPositionInYearSpinner.setValue(getPositionInYear());
+ }
+
+ /**
+ * Notifies the listener, if such, for a change in the selected date.
+ */
+ protected void notifyDateChanged() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ if (mMonthOrWeekChangedListener != null) {
+ mMonthOrWeekChangedListener.onMonthOrWeekChanged(this, getYear(), getPositionInYear());
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698