Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: flavienlaurent/datetimepicker
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: raymondlam/datetimepicker
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 7 commits
  • 10 files changed
  • 1 contributor

Commits on Dec 6, 2013

  1. Added setMinutesInterval for Time Picker Dialog to set the minimum se…

    …lectable increment for minutes.
    raymondlam committed Dec 6, 2013
    Copy the full SHA
    466a91c View commit details

Commits on Dec 11, 2013

  1. Copy the full SHA
    7e42c03 View commit details
  2. Added setDateRange to limit the number of months shown on the DateTim…

    …ePicker.
    
    Implemented month limit.
    raymondlam committed Dec 11, 2013
    Copy the full SHA
    6203ec0 View commit details
  3. Copy the full SHA
    54287f9 View commit details
  4. Disabled days outside of setDateRange.

    Removed limit on min year must be greater than max year.
    raymondlam committed Dec 11, 2013
    Copy the full SHA
    ce0465d View commit details

Commits on Jan 29, 2014

  1. Copy the full SHA
    f7d95b4 View commit details
  2. Copy the full SHA
    bfed03c View commit details
2 changes: 2 additions & 0 deletions datetimepicker-library/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -8,11 +8,13 @@
<color name="blue">#ff33b5e5</color>
<color name="darker_blue">#ff0099cc</color>
<color name="date_picker_text_normal">#ff999999</color>
<color name="date_picker_text_disabled">#ffcccccc</color>
<color name="calendar_header">#ff999999</color>
<color name="date_picker_view_animator">#fff2f2f2</color>

<color name="ampm_text_color">#8c8c8c</color>
<color name="numbers_text_color">#8c8c8c</color>
<color name="numbers_disable_text_color">#e3e3e3</color>

<color name="transparent_black">#7F000000</color>
</resources>
Original file line number Diff line number Diff line change
@@ -6,7 +6,15 @@ abstract interface DatePickerController {
public abstract int getMaxYear();

public abstract int getMinYear();

public abstract int getStartMonth();

public abstract int getEndMonth();

public abstract int getStartDay();

public abstract int getEndDay();

public abstract SimpleMonthAdapter.CalendarDay getSelectedDay();

public abstract void onDayOfMonthSelected(int year, int month, int day);
Original file line number Diff line number Diff line change
@@ -47,6 +47,10 @@ public class DatePickerDialog extends DialogFragment implements View.OnClickList
private HashSet<OnDateChangedListener> mListeners = new HashSet<OnDateChangedListener>();
private int mMaxYear = MAX_YEAR;
private int mMinYear = MIN_YEAR;
private int mStartMonth = 0;
private int mStartDay = 1;
private int mEndMonth = 11;
private int mEndDay = 31;
private LinearLayout mMonthAndDayView;
private String mSelectDay;
private String mSelectYear;
@@ -67,6 +71,31 @@ private void adjustDayInMonthIfNeeded(int month, int year) {
if (currentDay > day)
this.mCalendar.set(Calendar.DAY_OF_MONTH, day);
}

private void adjustDayAndMonthIfNeeded(int month, int year) {

if (year == this.mMinYear) {
if (month < mStartMonth) {
this.mCalendar.set(Calendar.MONTH, this.mStartMonth);
this.mCalendar.set(Calendar.DAY_OF_MONTH, this.mStartDay);
}
if (month == mStartMonth && this.mCalendar.get(Calendar.DAY_OF_MONTH) < this.mStartDay) {
this.mCalendar.set(Calendar.DAY_OF_MONTH, this.mStartDay);
}
}

if (year == this.mMaxYear) {
if (month > mEndMonth) {
this.mCalendar.set(Calendar.MONTH, this.mEndMonth);
this.mCalendar.set(Calendar.DAY_OF_MONTH, this.mEndDay);
}
if (month == mEndMonth && this.mCalendar.get(Calendar.DAY_OF_MONTH) > this.mEndDay) {
this.mCalendar.set(Calendar.DAY_OF_MONTH, this.mEndDay);
}
}
adjustDayInMonthIfNeeded(month, year);

}

public DatePickerDialog() {
// Empty constructor required for dialog fragment. DO NOT REMOVE
@@ -218,6 +247,10 @@ public View onCreateView(LayoutInflater layoutInflater, ViewGroup parent, Bundle
this.mWeekStart = bundle.getInt("week_start");
this.mMinYear = bundle.getInt("year_start");
this.mMaxYear = bundle.getInt("year_end");
this.mStartMonth = bundle.getInt("month_start");
this.mEndMonth = bundle.getInt("month_end");
this.mStartDay = bundle.getInt("day_start");
this.mEndDay = bundle.getInt("day_end");
currentView = bundle.getInt("current_view");
listPosition = bundle.getInt("list_position");
listPositionOffset = bundle.getInt("list_position_offset");
@@ -279,6 +312,10 @@ public void onSaveInstanceState(Bundle bundle) {
bundle.putInt("week_start", this.mWeekStart);
bundle.putInt("year_start", this.mMinYear);
bundle.putInt("year_end", this.mMaxYear);
bundle.putInt("month_start", this.mStartMonth);
bundle.putInt("month_end", this.mEndMonth);
bundle.putInt("day_start", this.mStartDay);
bundle.putInt("day_end", this.mEndDay);
bundle.putInt("current_view", this.mCurrentView);
int mostVisiblePosition = -1;
if (this.mCurrentView == 0)
@@ -292,7 +329,7 @@ public void onSaveInstanceState(Bundle bundle) {
}

public void onYearSelected(int year) {
adjustDayInMonthIfNeeded(this.mCalendar.get(Calendar.MONTH), year);
adjustDayAndMonthIfNeeded(this.mCalendar.get(Calendar.MONTH), year);
this.mCalendar.set(Calendar.YEAR, year);
updatePickers();
setCurrentView(0);
@@ -316,8 +353,6 @@ public void setOnDateSetListener(OnDateSetListener onDateSetListener) {
}

public void setYearRange(int minYear, int maxYear) {
if (maxYear <= minYear)
throw new IllegalArgumentException("Year end must be larger than year start");
if (maxYear > MAX_YEAR)
throw new IllegalArgumentException("max year end must < " + MAX_YEAR);
if (minYear < MIN_YEAR)
@@ -327,7 +362,72 @@ public void setYearRange(int minYear, int maxYear) {
if (this.mDayPickerView != null)
this.mDayPickerView.onChange();
}


/**
* Sets the start date for the DatePickerDialog.
*
* @param startYear The minimum year.
* @param startMonth The first valid month of the startYear. This must be a valid Calendar.Month. (0-11). Default is 0.
* @param startDay The first valid day of startMont (inclusive). Default is 1.
*/
public void setStartDate(int startYear, int startMonth, int startDay) {
setDateRange(startYear, startMonth, startDay, mMaxYear, mEndMonth, mEndDay);
}

/**
* Sets the end date for the DatePickerDialog.
*
* @param endYear The maximum year.
* @param endMonth The last valid month of the endYear. This must be a valid Calendar.Month. (0-11). Default is 11.
* @param endDay THe last valid day of endMonth (inclusive). Default is 31.
*/
public void setEndDate(int endYear, int endMonth, int endDay) {
setDateRange(mMinYear, mStartMonth, mStartDay, endYear, endMonth, endDay);
}

/**
* Sets the time period for the DatePickerDialog.
*
* @param startYear The minimum year.
* @param startMonth The first valid month of the startYear. This must be a valid Calendar.Month. (0-11). Default is 0.
* @param startDay The first valid day of startMont (inclusive). Default is 1.
* @param endYear The maximum year.
* @param endMonth The last valid month of the endYear. This must be a valid Calendar.Month. (0-11). Default is 11.
* @param endDay THe last valid day of endMonth (inclusive). Default is 31.
*/
public void setDateRange(int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) {
setYearRange(startYear, endYear);
if (startMonth >= 12 || startMonth < 0)
throw new IllegalArgumentException("startMonth must be between 0-11");
if (endMonth >= 12 || endMonth < 0)
throw new IllegalArgumentException("endMonth must be between 0-11");
this.mStartMonth = startMonth;
this.mStartDay = startDay;
this.mEndMonth = endMonth;
this.mEndDay = endDay;
}

@Override
public int getStartMonth() {
return this.mStartMonth;
}

@Override
public int getEndMonth() {
return this.mEndMonth;
}

@Override
public int getStartDay() {
return this.mStartDay;
}

@Override
public int getEndDay() {
return this.mEndDay;
}

public void tryVibrate() {
if (this.mVibrator != null && this.mVibrate) {
long timeInMillis = SystemClock.uptimeMillis();
@@ -345,4 +445,5 @@ static abstract interface OnDateChangedListener {
public static abstract interface OnDateSetListener {
public abstract void onDateSet(DatePickerDialog datePickerDialog, int year, int month, int day);
}

}
Original file line number Diff line number Diff line change
@@ -63,11 +63,13 @@ public int getMostVisiblePosition() {
}

public boolean goTo(SimpleMonthAdapter.CalendarDay calendarDay, boolean scrollToTop, boolean selectDay, boolean displayMonth) {
if (selectDay)
if (selectDay) {
this.mSelectedDay.set(calendarDay);
this.mAdapter.setSelectedDay(this.mSelectedDay);
}

this.mTempDay.set(calendarDay);
int monthIndex = 12 * (calendarDay.year - this.mController.getMinYear()) + calendarDay.month;
int monthIndex = 12 * (calendarDay.year - this.mController.getMinYear()) - this.mController.getStartMonth() + calendarDay.month;
postSetSelection(monthIndex);

// TODO improve
Original file line number Diff line number Diff line change
@@ -29,7 +29,8 @@ private boolean isSelectedDayInMonth(int year, int month) {
}

public int getCount() {
return 12 * (1 + (this.mController.getMaxYear() - this.mController.getMinYear()));
return 12 * (this.mController.getMaxYear() - this.mController.getMinYear())
+ this.mController.getEndMonth() - this.mController.getStartMonth() + 1;
}

public Object getItem(int position) {
@@ -54,17 +55,25 @@ public View getView(int position, View convertView, ViewGroup parent) {
if (monthParams == null)
monthParams = new HashMap<String, Integer>();
monthParams.clear();
int month = position % 12;
int year = position / 12 + this.mController.getMinYear();
int month = (position + this.mController.getStartMonth()) % 12;
int year = (position + this.mController.getStartMonth()) / 12 + this.mController.getMinYear();
Log.d("SimpleMonthAdapter", "Year: " + year + ", Month: " + month);
int selectedDay = -1;
if (isSelectedDayInMonth(year, month))
selectedDay = this.mSelectedDay.day;
int startDay = -1;
int endDay = 31;
if (this.mController.getStartMonth() == month && this.mController.getMinYear() == year)
startDay = this.mController.getStartDay();
if (this.mController.getEndMonth() == month && this.mController.getMaxYear() == year)
endDay = this.mController.getEndDay();
simpleMonthView.reuse();
monthParams.put("selected_day", Integer.valueOf(selectedDay));
monthParams.put("year", Integer.valueOf(year));
monthParams.put("month", Integer.valueOf(month));
monthParams.put("week_start", Integer.valueOf(this.mController.getFirstDayOfWeek()));
monthParams.put("start_day", Integer.valueOf(startDay));
monthParams.put("end_day", Integer.valueOf(endDay));
simpleMonthView.setMonthParams(monthParams);
simpleMonthView.invalidate();
return simpleMonthView;
Original file line number Diff line number Diff line change
@@ -63,6 +63,9 @@ public class SimpleMonthView extends View {
protected int mWeekStart = 1;
protected int mWidth;
protected int mYear;
protected int mDayDisabledTextColor;
protected int mStartDay;
protected int mEndDay;
private DateFormatSymbols mDateFormatSymbols = new DateFormatSymbols();

public SimpleMonthView(Context context) {
@@ -73,6 +76,7 @@ public SimpleMonthView(Context context) {
this.mDayOfWeekTypeface = resources.getString(R.string.day_of_week_label_typeface);
this.mMonthTitleTypeface = resources.getString(R.string.sans_serif);
this.mDayTextColor = resources.getColor(R.color.date_picker_text_normal);
this.mDayDisabledTextColor = resources.getColor(R.color.date_picker_text_disabled);
this.mTodayNumberColor = resources.getColor(R.color.blue);
this.mMonthTitleColor = resources.getColor(R.color.white);
this.mMonthTitleBGColor = resources.getColor(R.color.circle_background);
@@ -149,8 +153,11 @@ protected void drawMonthNums(Canvas canvas) {
int x = paddingDay * (1 + dayOffset * 2) + this.mPadding;
if (this.mSelectedDay == day)
canvas.drawCircle(x, y - MINI_DAY_NUMBER_TEXT_SIZE / 3, DAY_SELECTED_CIRCLE_SIZE, this.mSelectedCirclePaint);

if ((this.mHasToday) && (this.mToday == day))
this.mMonthNumPaint.setColor(this.mTodayNumberColor);
else if (day < this.mStartDay || day > this.mEndDay)
this.mMonthNumPaint.setColor(this.mDayDisabledTextColor);
else
this.mMonthNumPaint.setColor(this.mDayTextColor);
canvas.drawText(String.format("%d", day), x, y, this.mMonthNumPaint);
@@ -171,7 +178,9 @@ public SimpleMonthAdapter.CalendarDay getDayFromLocation(float x, float y) {

int yDay = (int) (y - MONTH_HEADER_SIZE) / this.mRowHeight;
int day = 1 + ((int) ((x - padding) * this.mNumDays / (this.mWidth - padding - this.mPadding)) - findDayOffset()) + yDay * this.mNumDays;

// If day out of range
if (day < this.mStartDay || day > this.mEndDay)
return null;
return new SimpleMonthAdapter.CalendarDay(this.mYear, this.mMonth, day);
}

@@ -254,6 +263,8 @@ public void setMonthParams(HashMap<String, Integer> monthParams) {
this.mSelectedDay = ((Integer) monthParams.get("selected_day")).intValue();
this.mMonth = ((Integer) monthParams.get("month")).intValue();
this.mYear = ((Integer) monthParams.get("year")).intValue();
this.mStartDay = ((Integer) monthParams.get("start_day")).intValue();
this.mEndDay = ((Integer) monthParams.get("end_day")).intValue();
Time time = new Time(Time.getCurrentTimezone());
time.setToNow();
this.mHasToday = false;
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
*/

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Service;
import android.content.Context;
import android.content.res.Resources;
@@ -94,6 +95,8 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
private AnimatorSet mTransition;
private Handler mHandler = new Handler();

private int mMinutesInterval = 1;

public interface OnValueSelectedListener {
void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance);
}
@@ -171,7 +174,7 @@ public void setOnValueSelectedListener(OnValueSelectedListener listener) {
* @param is24HourMode
*/
public void initialize(Context context, int initialHoursOfDay, int initialMinutes,
boolean is24HourMode, boolean vibrate) {
boolean is24HourMode, boolean vibrate, int minutesInterval) {
if (mTimeInitialized) {
Log.e(TAG, "Time has already been initialized.");
return;
@@ -203,10 +206,17 @@ public void initialize(Context context, int initialHoursOfDay, int initialMinute
innerHoursTexts[i] = String.format("%d", hours[i]);
minutesTexts[i] = String.format("%02d", minutes[i]);
}

mMinutesInterval = minutesInterval;
boolean[] minutesEnabled = new boolean[12];
for (int i = 0; i < 12; i++) {
minutesEnabled[i] = (i*5 % minutesInterval == 0);
}

mHourRadialTextsView.initialize(res,
hoursTexts, (is24HourMode ? innerHoursTexts : null), mHideAmPm, true);
hoursTexts, (is24HourMode ? innerHoursTexts : null), null, mHideAmPm, true);
mHourRadialTextsView.invalidate();
mMinuteRadialTextsView.initialize(res, minutesTexts, null, mHideAmPm, false);
mMinuteRadialTextsView.initialize(res, minutesTexts, null, minutesEnabled, mHideAmPm, false);
mMinuteRadialTextsView.invalidate();

// Initialize the currently-selected hour and minute.
@@ -374,6 +384,20 @@ private void preparePrefer30sMap() {
}
}

/**
* Snaps to the nearest valid minute value.
*/
private int snapValid(int degrees) {
int stepSize = 360 / (60 / mMinutesInterval);
int floor = (degrees/stepSize) * stepSize;
int ceiling = floor + stepSize;
if ((degrees - floor) < (ceiling - degrees)) {
return floor;
} else {
return ceiling;
}
}

/**
* Returns mapping of any input degrees (0 to 360) to one of 60 selectable output degrees,
* where the degrees corresponding to visible numbers (i.e. those divisible by 30) will be
@@ -442,7 +466,10 @@ private int reselectSelector(int degrees, boolean isInnerCircle,

int stepSize;
boolean allowFineGrained = !forceToVisibleValue && (currentShowing == MINUTE_INDEX);
if (allowFineGrained) {
// Check if we have a minute interval
if (currentShowing == MINUTE_INDEX && mMinutesInterval != 1) {
degrees = snapValid(degrees);
} else if (allowFineGrained) {
degrees = snapPrefer30s(degrees);
} else {
degrees = snapOnly30s(degrees, 0);
@@ -773,6 +800,7 @@ public boolean trySettingInputEnabled(boolean inputEnabled) {
* Necessary for accessibility, to ensure we support "scrolling" forward and backward
* in the circle.
*/
@TargetApi(14)
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
if (Build.VERSION.SDK_INT >= 14) {
super.onInitializeAccessibilityNodeInfo(info);
Loading