Merge "Fix min/max date range in DatePicker calendar mode" into lmp-mr1-dev

automerge: 3847552

* commit '384755230c52f0951820ba496f300959dcc84ead':
  Fix min/max date range in DatePicker calendar mode
This commit is contained in:
Alan Viverette
2014-10-27 23:41:44 +00:00
committed by android-build-merger
6 changed files with 126 additions and 115 deletions

View File

@@ -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
@@ -453,36 +455,6 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i
return mCurrentDate.getFirstDayOfWeek();
}
@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);

View File

@@ -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();
}

View File

@@ -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.

View File

@@ -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);
}
}

View File

@@ -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);
}
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);

View File

@@ -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);