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

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

Issue 15057004: Week picker for android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed week_year. Added BaseDatePicker. Created 7 years, 7 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/WeekPicker.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java b/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbcb3654074da85520840b233d98b60d92f93e36
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java
@@ -0,0 +1,330 @@
+// Copyright (c) 2012 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.content.res.Configuration;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.NumberPicker;
+import android.widget.NumberPicker.OnValueChangeListener;
+
+import java.text.DateFormatSymbols;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Locale;
+
+import org.chromium.content.R;
+
+// This class is heavily based on android.widget.DatePicker.
+public class WeekPicker extends BaseDatePicker {
+
+ private final NumberPicker mWeekSpinner;
+
+ private final NumberPicker mYearSpinner;
+
+ private OnWeekChangedListener mWeekChangedListener;
+
+ /**
+ * The callback used to indicate the user changes\d the date.
+ */
+ public interface OnWeekChangedListener {
+
+ /**
+ * Called upon a date change.
+ *
+ * @param view The view associated with this listener.
+ * @param year The year that was set.
+ * @param weekOfYear The week in year.
+ */
+ void onWeekChanged(WeekPicker view, int year, int weekOfYear);
+ }
+
+ public WeekPicker(Context context) {
+ this(context, null);
+ }
+
+ public WeekPicker(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.datePickerStyle);
+ }
+
+ public WeekPicker(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.week_picker, this, true);
+
+ OnValueChangeListener onChangeListener = new OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ // take care of wrapping of weeks to update greater fields
+ if (picker == mWeekSpinner) {
+ Calendar tempDate = (Calendar) mCurrentDate.clone();
+ if (oldVal == mWeekSpinner.getMaxValue()
+ && newVal == mWeekSpinner.getMinValue()) {
+ tempDate.add(Calendar.WEEK_OF_YEAR, 1);
+ } else if (oldVal == mWeekSpinner.getMinValue()
+ && newVal == mWeekSpinner.getMaxValue()) {
+ tempDate.add(Calendar.WEEK_OF_YEAR, -1);
+ } else {
+ tempDate.add(Calendar.WEEK_OF_YEAR, newVal - oldVal);
+ }
+ // now set the date to the adjusted one
+ setDate(getISOWeekYearForDate(tempDate),
+ getWeekForDate(tempDate));
+ } else if (picker == mYearSpinner) {
+ setDate(newVal, getWeekForDate(mCurrentDate));
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ updateSpinners();
+ notifyDateChanged();
+ }
+ };
+
+ // week
+ mWeekSpinner = (NumberPicker) findViewById(R.id.week);
+ mWeekSpinner.setOnLongPressUpdateInterval(200);
+ mWeekSpinner.setOnValueChangedListener(onChangeListener);
+
+ // year
+ mYearSpinner = (NumberPicker) findViewById(R.id.year);
+ mYearSpinner.setOnLongPressUpdateInterval(100);
+ mYearSpinner.setOnValueChangedListener(onChangeListener);
+
+ // initialize to current date
+ mCurrentDate.setTimeInMillis(System.currentTimeMillis());
+ init(getISOWeekYearForDate(mCurrentDate), getWeekForDate(mCurrentDate), null);
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (mIsEnabled == enabled) {
+ return;
+ }
+ super.setEnabled(enabled);
+ mWeekSpinner.setEnabled(enabled);
+ mYearSpinner.setEnabled(enabled);
+ }
+
+ @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);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ setCurrentLocale(newConfig.locale);
+ }
+
+ /**
+ * Updates the current date.
+ *
+ * @param year The year.
+ * @param week The week in year.
+ */
+ public void updateWeek(int year, int week) {
+ if (!isNewDate(year, week)) {
+ return;
+ }
+ setDate(year, week);
+ updateSpinners();
+ notifyDateChanged();
+ }
+
+ // Override so we are in complete control of save / restore for this widget.
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+ dispatchThawSelfOnly(container);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ return new SavedState(superState, getYear(), getWeek());
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Parcelable state) {
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ setDate(ss.mYear, ss.mWeek);
+ updateSpinners();
+ }
+
+ /**
+ * Initialize the state. If the provided values designate an inconsistent
+ * date the values are normalized before updating the spinners.
+ *
+ * @param year The initial week year.
+ * @param weekOfYear The initial week in year.
+ * @param onWeekChangedListener How user is notified date is changed by
+ * user, can be null.
+ */
+ public void init(int year, int weekOfYear, OnWeekChangedListener onWeekChangedListener) {
+ setDate(year, weekOfYear);
+ updateSpinners();
+ mWeekChangedListener = onWeekChangedListener;
+ }
+
+ private boolean isNewDate(int year, int week) {
+ return (getYear() != year || getWeek() != week);
+ }
+
+ private Calendar createDateFromWeek(int year, int week) {
+ Calendar date = getCalendarForLocale(null, mCurrentLocale);
+ date.set(Calendar.YEAR, year);
+ date.set(Calendar.WEEK_OF_YEAR, week);
+ return date;
+ }
+
+ public static int getISOWeekYearForDate(Calendar date) {
+ int year = date.get(Calendar.YEAR);
+ int month = date.get(Calendar.MONTH);
+ int week = date.get(Calendar.WEEK_OF_YEAR);
+ if (month == 0 && week > 51) {
+ year--;
+ } else if (month == 11 && week == 1) {
+ year++;
+ }
+ return year;
+ }
+
+ public static int getWeekForDate(Calendar date) {
+ return date.get(Calendar.WEEK_OF_YEAR);
+ }
+
+ private void setDate(int year, int week) {
+ mCurrentDate = createDateFromWeek(year, week);
+ if (mCurrentDate.before(mMinDate)) {
+ mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+ } else if (mCurrentDate.after(mMaxDate)) {
+ mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+ }
+ }
+
+ private int getNumberOfWeeks() {
+ // Create a date in the middle of the year, where the week year matches the year.
+ Calendar date = createDateFromWeek(getYear(), 20);
+ return date.getActualMaximum(Calendar.WEEK_OF_YEAR);
+ }
+
+ private void updateSpinners() {
+ // set the spinner ranges respecting the min and max dates
+ if (mCurrentDate.equals(mMinDate)) {
+ mWeekSpinner.setMinValue(getWeekForDate(mCurrentDate));
+ mWeekSpinner.setMaxValue(getNumberOfWeeks());
+ mWeekSpinner.setWrapSelectorWheel(false);
+ } else if (mCurrentDate.equals(mMaxDate)) {
+ mWeekSpinner.setMinValue(getNumberOfWeeks());
+ mWeekSpinner.setMaxValue(getWeekForDate(mCurrentDate));
+ mWeekSpinner.setWrapSelectorWheel(false);
+ } else {
+ mWeekSpinner.setMinValue(1);
+ mWeekSpinner.setMaxValue(getNumberOfWeeks());
+ mWeekSpinner.setWrapSelectorWheel(true);
+ }
+
+ // year spinner range does not change based on the current date
+ mYearSpinner.setMinValue(getISOWeekYearForDate(mMinDate));
+ mYearSpinner.setMaxValue(getISOWeekYearForDate(mMaxDate));
+ mYearSpinner.setWrapSelectorWheel(false);
+
+ // set the spinner values
+ mYearSpinner.setValue(getISOWeekYearForDate(mCurrentDate));
+ mWeekSpinner.setValue(getWeekForDate(mCurrentDate));
+ }
+
+ /**
+ * @return The selected year.
+ */
+ public int getYear() {
+ return getISOWeekYearForDate(mCurrentDate);
+ }
+
+ /**
+ * @return The selected week.
+ */
+ public int getWeek() {
+ return getWeekForDate(mCurrentDate);
+ }
+
+ /**
+ * Notifies the listener, if such, for a change in the selected date.
+ */
+ private void notifyDateChanged() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ if (mWeekChangedListener != null) {
+ mWeekChangedListener.onWeekChanged(this, getYear(), getWeek());
+ }
+ }
+
+ /**
+ * Class for managing state storing/restoring.
+ */
+ private static class SavedState extends BaseSavedState {
+
+ private final int mYear;
+
+ private final int mWeek;
+
+ /**
+ * Constructor called from {@link DatePicker#onSaveInstanceState()}
+ */
+ private SavedState(Parcelable superState, int year, int week) {
+ super(superState);
+ mYear = year;
+ mWeek = week;
+ }
+
+ /**
+ * Constructor called from {@link #CREATOR}
+ */
+ private SavedState(Parcel in) {
+ super(in);
+ mYear = in.readInt();
+ mWeek = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mYear);
+ dest.writeInt(mWeek);
+ }
+
+ @SuppressWarnings("all")
+ // suppress unused and hiding
+ public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
+
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698