summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2014-10-24 14:34:26 -0700
committerAlan Viverette <alanv@google.com>2014-10-24 14:37:29 -0700
commit50eb025c2fea7e364e0be951ce8ba6ca605f901a (patch)
tree2c61860100aafc3adfef66a5912fa2204aa6e892 /core/java/android/widget
parentcc66a236f90cbef7f9562b4179c3aec517f4f082 (diff)
downloadframeworks_base-50eb025c2fea7e364e0be951ce8ba6ca605f901a.zip
frameworks_base-50eb025c2fea7e364e0be951ce8ba6ca605f901a.tar.gz
frameworks_base-50eb025c2fea7e364e0be951ce8ba6ca605f901a.tar.bz2
Fix min/max date range in DatePicker calendar mode
Also cleans abstraction of various day/year pickers and adapters. BUG: 18104457 Change-Id: Ifde664788d8123a3123303940bac63c1350c2cd7
Diffstat (limited to 'core/java/android/widget')
-rw-r--r--core/java/android/widget/DatePickerCalendarDelegate.java40
-rw-r--r--core/java/android/widget/DatePickerController.java15
-rw-r--r--core/java/android/widget/DayPickerView.java69
-rw-r--r--core/java/android/widget/SimpleMonthAdapter.java65
-rw-r--r--core/java/android/widget/SimpleMonthView.java20
-rw-r--r--core/java/android/widget/YearPickerView.java32
6 files changed, 126 insertions, 115 deletions
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index e71b383..64c81e0 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -21,13 +21,11 @@ import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.util.AttributeSet;
-import android.util.SparseArray;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.View;
@@ -186,6 +184,8 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
headerSelectedTextColor));
mDayPickerView = new DayPickerView(mContext, this);
+ mDayPickerView.setRange(mMinDate, mMaxDate);
+
mYearPickerView = new YearPickerView(mContext);
mYearPickerView.init(this);
@@ -411,7 +411,8 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
updateDisplay(false);
}
mMinDate.setTimeInMillis(minDate);
- mDayPickerView.goTo(getSelectedDay(), false, true, true);
+ mDayPickerView.setRange(mMinDate, mMaxDate);
+ mYearPickerView.setRange(mMinDate, mMaxDate);
}
@Override
@@ -432,7 +433,8 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
updateDisplay(false);
}
mMaxDate.setTimeInMillis(maxDate);
- mDayPickerView.goTo(getSelectedDay(), false, true, true);
+ mDayPickerView.setRange(mMinDate, mMaxDate);
+ mYearPickerView.setRange(mMinDate, mMaxDate);
}
@Override
@@ -454,36 +456,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
}
@Override
- public int getMinYear() {
- return mMinDate.get(Calendar.YEAR);
- }
-
- @Override
- public int getMaxYear() {
- return mMaxDate.get(Calendar.YEAR);
- }
-
- @Override
- public int getMinMonth() {
- return mMinDate.get(Calendar.MONTH);
- }
-
- @Override
- public int getMaxMonth() {
- return mMaxDate.get(Calendar.MONTH);
- }
-
- @Override
- public int getMinDay() {
- return mMinDate.get(Calendar.DAY_OF_MONTH);
- }
-
- @Override
- public int getMaxDay() {
- return mMaxDate.get(Calendar.DAY_OF_MONTH);
- }
-
- @Override
public void setEnabled(boolean enabled) {
mMonthAndDayLayout.setEnabled(enabled);
mHeaderYearTextView.setEnabled(enabled);
diff --git a/core/java/android/widget/DatePickerController.java b/core/java/android/widget/DatePickerController.java
index 059709d..ea6ec61 100644
--- a/core/java/android/widget/DatePickerController.java
+++ b/core/java/android/widget/DatePickerController.java
@@ -38,20 +38,5 @@ interface DatePickerController {
void setFirstDayOfWeek(int firstDayOfWeek);
int getFirstDayOfWeek();
- int getMinYear();
- int getMaxYear();
-
- int getMinMonth();
- int getMaxMonth();
-
- int getMinDay();
- int getMaxDay();
-
- void setMinDate(long minDate);
- Calendar getMinDate();
-
- void setMaxDate(long maxDate);
- Calendar getMaxDate();
-
void tryVibrate();
}
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index ca4095e..fcf66f6 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -25,6 +25,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.MathUtils;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
@@ -57,9 +58,11 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener,
// highlighted time
private Calendar mSelectedDay = Calendar.getInstance();
- private SimpleMonthAdapter mAdapter;
-
private Calendar mTempDay = Calendar.getInstance();
+ private Calendar mMinDate = Calendar.getInstance();
+ private Calendar mMaxDate = Calendar.getInstance();
+
+ private SimpleMonthAdapter mAdapter;
// which month should be displayed/highlighted [0-11]
private int mCurrentMonthDisplayed;
@@ -75,6 +78,7 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener,
public DayPickerView(Context context, DatePickerController controller) {
super(context);
+
init();
setController(controller);
}
@@ -97,6 +101,41 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener,
setUpListView();
}
+ public void setRange(Calendar minDate, Calendar maxDate) {
+ mMinDate.setTimeInMillis(minDate.getTimeInMillis());
+ mMaxDate.setTimeInMillis(maxDate.getTimeInMillis());
+
+ mAdapter.setRange(mMinDate, mMaxDate);
+
+ if (constrainCalendar(mSelectedDay, mMinDate, mMaxDate)) {
+ goTo(mSelectedDay, false, true, true);
+ }
+ }
+
+ /**
+ * Constrains the supplied calendar to stay within the min and max
+ * calendars, returning <code>true</code> if the supplied calendar
+ * was modified.
+ *
+ * @param value The calendar to constrain
+ * @param min The minimum calendar
+ * @param max The maximum calendar
+ * @return True if <code>value</code> was modified
+ */
+ private boolean constrainCalendar(Calendar value, Calendar min, Calendar max) {
+ if (value.compareTo(min) < 0) {
+ value.setTimeInMillis(min.getTimeInMillis());
+ return true;
+ }
+
+ if (value.compareTo(max) > 0) {
+ value.setTimeInMillis(max.getTimeInMillis());
+ return true;
+ }
+
+ return false;
+ }
+
public void onChange() {
setUpAdapter();
setAdapter(mAdapter);
@@ -137,23 +176,16 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener,
setFriction(ViewConfiguration.getScrollFriction() * mFriction);
}
- private int getDiffMonths(Calendar start, Calendar end){
+ private int getDiffMonths(Calendar start, Calendar end) {
final int diffYears = end.get(Calendar.YEAR) - start.get(Calendar.YEAR);
final int diffMonths = end.get(Calendar.MONTH) - start.get(Calendar.MONTH) + 12 * diffYears;
return diffMonths;
}
private int getPositionFromDay(Calendar day) {
- final int diffMonthMax = getDiffMonths(mController.getMinDate(), mController.getMaxDate());
- int diffMonth = getDiffMonths(mController.getMinDate(), day);
-
- if (diffMonth < 0 ) {
- diffMonth = 0;
- } else if (diffMonth > diffMonthMax) {
- diffMonth = diffMonthMax;
- }
-
- return diffMonth;
+ final int diffMonthMax = getDiffMonths(mMinDate, mMaxDate);
+ final int diffMonth = getDiffMonths(mMinDate, day);
+ return MathUtils.constrain(diffMonth, 0, diffMonthMax);
}
/**
@@ -171,8 +203,7 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener,
* visible
* @return Whether or not the view animated to the new location
*/
- public boolean goTo(Calendar day, boolean animate, boolean setSelected,
- boolean forceScroll) {
+ public boolean goTo(Calendar day, boolean animate, boolean setSelected, boolean forceScroll) {
// Set the selected day
if (setSelected) {
@@ -464,10 +495,10 @@ class DayPickerView extends ListView implements AbsListView.OnScrollListener,
}
// Figure out what month is showing.
- int firstVisiblePosition = getFirstVisiblePosition();
- int month = firstVisiblePosition % 12;
- int year = firstVisiblePosition / 12 + mController.getMinYear();
- Calendar day = Calendar.getInstance();
+ final int firstVisiblePosition = getFirstVisiblePosition();
+ final int month = firstVisiblePosition % 12;
+ final int year = firstVisiblePosition / 12 + mMinDate.get(Calendar.YEAR);
+ final Calendar day = Calendar.getInstance();
day.set(year, month, 1);
// Scroll either forward or backward one month.
diff --git a/core/java/android/widget/SimpleMonthAdapter.java b/core/java/android/widget/SimpleMonthAdapter.java
index 3bad235..5aa78c8 100644
--- a/core/java/android/widget/SimpleMonthAdapter.java
+++ b/core/java/android/widget/SimpleMonthAdapter.java
@@ -28,21 +28,30 @@ import java.util.HashMap;
* An adapter for a list of {@link android.widget.SimpleMonthView} items.
*/
class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayClickListener {
- private static final String TAG = "SimpleMonthAdapter";
+ private final Calendar mMinDate = Calendar.getInstance();
+ private final Calendar mMaxDate = Calendar.getInstance();
private final Context mContext;
private final DatePickerController mController;
- private Calendar mSelectedDay;
+ private Calendar mSelectedDay;
private ColorStateList mCalendarTextColors;
public SimpleMonthAdapter(Context context, DatePickerController controller) {
mContext = context;
mController = controller;
+
init();
setSelectedDay(mController.getSelectedDay());
}
+ public void setRange(Calendar min, Calendar max) {
+ mMinDate.setTimeInMillis(min.getTimeInMillis());
+ mMaxDate.setTimeInMillis(max.getTimeInMillis());
+
+ notifyDataSetInvalidated();
+ }
+
/**
* Updates the selected day and related parameters.
*
@@ -68,10 +77,9 @@ class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayCli
@Override
public int getCount() {
- final int diffYear = mController.getMaxYear() - mController.getMinYear();
- final int diffMonth = 1 + mController.getMaxMonth() - mController.getMinMonth()
- + 12 * diffYear;
- return diffMonth;
+ final int diffYear = mMaxDate.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
+ final int diffMonth = mMaxDate.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
+ return diffMonth + 12 * diffYear + 1;
}
@Override
@@ -92,36 +100,34 @@ class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayCli
@SuppressWarnings("unchecked")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- SimpleMonthView v;
- HashMap<String, Integer> drawingParams = null;
+ final SimpleMonthView v;
if (convertView != null) {
v = (SimpleMonthView) convertView;
- // We store the drawing parameters in the view so it can be recycled
- drawingParams = (HashMap<String, Integer>) v.getTag();
} else {
v = new SimpleMonthView(mContext);
+
// Set up the new view
- AbsListView.LayoutParams params = new AbsListView.LayoutParams(
+ final AbsListView.LayoutParams params = new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.MATCH_PARENT);
v.setLayoutParams(params);
v.setClickable(true);
v.setOnDayClickListener(this);
+
if (mCalendarTextColors != null) {
v.setTextColor(mCalendarTextColors);
}
}
- if (drawingParams == null) {
- drawingParams = new HashMap<String, Integer>();
- } else {
- drawingParams.clear();
- }
- final int currentMonth = position + mController.getMinMonth();
- final int month = currentMonth % 12;
- final int year = currentMonth / 12 + mController.getMinYear();
- int selectedDay = -1;
+ final int minMonth = mMinDate.get(Calendar.MONTH);
+ final int minYear = mMinDate.get(Calendar.YEAR);
+ final int currentMonth = position + minMonth;
+ final int month = currentMonth % 12;
+ final int year = currentMonth / 12 + minYear;
+ final int selectedDay;
if (isSelectedDayInMonth(year, month)) {
selectedDay = mSelectedDay.get(Calendar.DAY_OF_MONTH);
+ } else {
+ selectedDay = -1;
}
// Invokes requestLayout() to ensure that the recycled view is set with the appropriate
@@ -129,15 +135,15 @@ class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayCli
v.reuse();
final int enabledDayRangeStart;
- if (mController.getMinMonth() == month && mController.getMinYear() == year) {
- enabledDayRangeStart = mController.getMinDay();
+ if (minMonth == month && minYear == year) {
+ enabledDayRangeStart = mMinDate.get(Calendar.DAY_OF_MONTH);
} else {
enabledDayRangeStart = 1;
}
final int enabledDayRangeEnd;
- if (mController.getMaxMonth() == month && mController.getMaxYear() == year) {
- enabledDayRangeEnd = mController.getMaxDay();
+ if (mMaxDate.get(Calendar.MONTH) == month && mMaxDate.get(Calendar.YEAR) == year) {
+ enabledDayRangeEnd = mMaxDate.get(Calendar.DAY_OF_MONTH);
} else {
enabledDayRangeEnd = 31;
}
@@ -155,20 +161,25 @@ class SimpleMonthAdapter extends BaseAdapter implements SimpleMonthView.OnDayCli
@Override
public void onDayClick(SimpleMonthView view, Calendar day) {
- if (day != null) {
- onDayTapped(day);
+ if (day != null && isCalendarInRange(day)) {
+ onDaySelected(day);
}
}
+ private boolean isCalendarInRange(Calendar value) {
+ return value.compareTo(mMinDate) >= 0 && value.compareTo(mMaxDate) <= 0;
+ }
+
/**
* Maintains the same hour/min/sec but moves the day to the tapped day.
*
* @param day The day that was tapped
*/
- protected void onDayTapped(Calendar day) {
+ private void onDaySelected(Calendar day) {
mController.tryVibrate();
mController.onDayOfMonthSelected(day.get(Calendar.YEAR), day.get(Calendar.MONTH),
day.get(Calendar.DAY_OF_MONTH));
+
setSelectedDay(day);
}
}
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 59baaba..d2a37ac 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -52,8 +52,6 @@ import java.util.Locale;
* within the specified month.
*/
class SimpleMonthView extends View {
- private static final String TAG = "SimpleMonthView";
-
private static final int DEFAULT_HEIGHT = 32;
private static final int MIN_HEIGHT = 10;
@@ -67,15 +65,15 @@ class SimpleMonthView extends View {
private static final int DAY_SEPARATOR_WIDTH = 1;
+ private final Formatter mFormatter;
+ private final StringBuilder mStringBuilder;
+
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;
-
/** Single-letter (when available) formatter for the day of week label. */
private SimpleDateFormat mDayFormatter = new SimpleDateFormat("EEEEE", Locale.getDefault());
@@ -92,9 +90,6 @@ class SimpleMonthView extends View {
private Paint mMonthTitlePaint;
private Paint mMonthDayLabelPaint;
- private final Formatter mFormatter;
- private final StringBuilder mStringBuilder;
-
private int mMonth;
private int mYear;
@@ -155,11 +150,14 @@ class SimpleMonthView extends View {
this(context, attrs, R.attr.datePickerStyle);
}
- public SimpleMonthView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs);
+ public SimpleMonthView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
- final Resources res = context.getResources();
+ public SimpleMonthView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ final Resources res = context.getResources();
mDayOfWeekTypeface = res.getString(R.string.day_of_week_label_typeface);
mMonthTitleTypeface = res.getString(R.string.sans_serif);
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 2bf07f9..24ed7ce 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -18,7 +18,6 @@ package android.widget;
import android.content.Context;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -33,10 +32,15 @@ import com.android.internal.R;
*/
class YearPickerView extends ListView implements AdapterView.OnItemClickListener,
OnDateChangedListener {
+ private final Calendar mMinDate = Calendar.getInstance();
+ private final Calendar mMaxDate = Calendar.getInstance();
+
+ private final YearAdapter mAdapter;
+ private final int mViewSize;
+ private final int mChildSize;
+
private DatePickerController mController;
- private YearAdapter mAdapter;
- private int mViewSize;
- private int mChildSize;
+
private int mSelectedPosition = -1;
private int mYearSelectedCircleColor;
@@ -72,15 +76,23 @@ class YearPickerView extends ListView implements AdapterView.OnItemClickListener
setOnItemClickListener(this);
setDividerHeight(0);
+
+ mAdapter = new YearAdapter(getContext(), R.layout.year_label_text_view);
+ setAdapter(mAdapter);
+ }
+
+ public void setRange(Calendar min, Calendar max) {
+ mMinDate.setTimeInMillis(min.getTimeInMillis());
+ mMaxDate.setTimeInMillis(max.getTimeInMillis());
+
+ updateAdapterData();
}
public void init(DatePickerController controller) {
mController = controller;
mController.registerOnDateChangedListener(this);
- mAdapter = new YearAdapter(getContext(), R.layout.year_label_text_view);
updateAdapterData();
- setAdapter(mAdapter);
onDateChanged();
}
@@ -98,8 +110,9 @@ class YearPickerView extends ListView implements AdapterView.OnItemClickListener
private void updateAdapterData() {
mAdapter.clear();
- final int maxYear = mController.getMaxYear();
- for (int year = mController.getMinYear(); year <= maxYear; year++) {
+
+ final int maxYear = mMaxDate.get(Calendar.YEAR);
+ for (int year = mMinDate.get(Calendar.YEAR); year <= maxYear; year++) {
mAdapter.add(year);
}
}
@@ -173,12 +186,13 @@ class YearPickerView extends ListView implements AdapterView.OnItemClickListener
updateAdapterData();
mAdapter.notifyDataSetChanged();
postSetSelectionCentered(
- mController.getSelectedDay().get(Calendar.YEAR) - mController.getMinYear());
+ mController.getSelectedDay().get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR));
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
+
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
event.setFromIndex(0);
event.setToIndex(0);