From 0817c10f8f02fd248c0372041e9738d1f6b51bec Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Fri, 13 May 2016 16:10:38 -0400 Subject: [PATCH 01/26] Refactor using State builder --- .../MaterialCalendarView.java | 308 ++++++++++-------- .../sample/BasicActivityDecorated.java | 17 +- .../sample/CustomizeCodeActivity.java | 11 +- .../sample/DisableDaysActivity.java | 13 +- .../sample/DynamicSettersActivity.java | 21 +- .../SwappableBasicActivityDecorated.java | 26 +- 6 files changed, 237 insertions(+), 159 deletions(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 7f807895..84b3f8c7 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -66,6 +66,9 @@ */ public class MaterialCalendarView extends ViewGroup { + static volatile State singleton = null; + private State state; + /** * {@linkplain IntDef} annotation for selection mode. * @@ -273,7 +276,11 @@ public void transformPage(View page, float position) { //Allowing use of Calendar.getInstance() here as a performance optimization firstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek(); } - setCalendarDisplayMode(CalendarMode.values()[calendarModeIndex]); + + newState() + .setFirstDayOfWeek(firstDayOfWeek) + .setCalendarDisplayMode(CalendarMode.values()[calendarModeIndex]) + .commit(); final int tileSize = a.getDimensionPixelSize(R.styleable.MaterialCalendarView_mcv_tileSize, -1); if (tileSize > 0) { @@ -348,7 +355,6 @@ public void transformPage(View page, float position) { R.styleable.MaterialCalendarView_mcv_allowClickDaysOutsideCurrentMonth, true )); - } catch (Exception e) { e.printStackTrace(); } finally { @@ -469,50 +475,6 @@ public void goToNext() { } } - /** - * Set calendar display mode. The default mode is Months. - * When switching between modes will select todays date, or the selected date, - * if selection mode is single. - * - * @param mode - calendar mode - */ - @Experimental - public void setCalendarDisplayMode(CalendarMode mode) { - if (calendarMode != null && calendarMode.equals(mode)) { - return; - } - - CalendarPagerAdapter newAdapter; - switch (mode) { - case MONTHS: - newAdapter = new MonthPagerAdapter(this); - break; - case WEEKS: - newAdapter = new WeekPagerAdapter(this); - break; - default: - throw new IllegalArgumentException("Provided display mode which is not yet implemented"); - } - if (adapter == null) { - adapter = newAdapter; - } else { - adapter = adapter.migrateStateAndReturn(newAdapter); - } - pager.setAdapter(adapter); - setRangeDates(minDate, maxDate); - calendarMode = mode; - - // Reset height params after mode change - pager.setLayoutParams(new LayoutParams(calendarMode.visibleWeeksCount + DAY_NAMES_ROW)); - - setCurrentDate( - selectionMode == SELECTION_MODE_SINGLE && !adapter.getSelectedDates().isEmpty() - ? adapter.getSelectedDates().get(0) - : CalendarDay.today()); - invalidateDecorators(); - updateUi(); - } - /** * Get the current selection mode. The default mode is {@linkplain #SELECTION_MODE_SINGLE} * @@ -907,28 +869,6 @@ public CalendarDay getMinimumDate() { return minDate; } - /** - * @param calendar set the minimum selectable date, null for no minimum - */ - public void setMinimumDate(@Nullable Calendar calendar) { - setMinimumDate(CalendarDay.from(calendar)); - } - - /** - * @param date set the minimum selectable date, null for no minimum - */ - public void setMinimumDate(@Nullable Date date) { - setMinimumDate(CalendarDay.from(date)); - } - - /** - * @param calendar set the minimum selectable date, null for no minimum - */ - public void setMinimumDate(@Nullable CalendarDay calendar) { - minDate = calendar; - setRangeDates(minDate, maxDate); - } - /** * @return the maximum selectable date for the calendar, if any */ @@ -936,28 +876,6 @@ public CalendarDay getMaximumDate() { return maxDate; } - /** - * @param calendar set the maximum selectable date, null for no maximum - */ - public void setMaximumDate(@Nullable Calendar calendar) { - setMaximumDate(CalendarDay.from(calendar)); - } - - /** - * @param date set the maximum selectable date, null for no maximum - */ - public void setMaximumDate(@Nullable Date date) { - setMaximumDate(CalendarDay.from(date)); - } - - /** - * @param calendar set the maximum selectable date, null for no maximum - */ - public void setMaximumDate(@Nullable CalendarDay calendar) { - maxDate = calendar; - setRangeDates(minDate, maxDate); - } - /** * The default value is {@link #SHOW_DEFAULTS}, which currently is just {@link #SHOW_DECORATED_DISABLED}. * This means that the default visible days are of the current month, in the min-max range. @@ -1141,14 +1059,19 @@ protected void onRestoreInstanceState(Parcelable state) { for (CalendarDay calendarDay : ss.selectedDates) { setDateSelected(calendarDay, true); } - setFirstDayOfWeek(ss.firstDayOfWeek); setTileWidth(ss.tileWidthPx); setTileHeight(ss.tileHeightPx); setTopbarVisible(ss.topbarVisible); setSelectionMode(ss.selectionMode); setDynamicHeightEnabled(ss.dynamicHeightEnabled); - setCalendarDisplayMode(ss.calendarMode); setCurrentDate(ss.currentMonth); + + newState() + .setFirstDayOfWeek(ss.firstDayOfWeek) + .setCalendarDisplayMode(ss.calendarMode) + .setMinimumDate(ss.minDate) + .setMaximumDate(ss.maxDate) + .commit(); } @Override @@ -1259,46 +1182,6 @@ private static int getThemeAccentColor(Context context) { return outValue.data; } - /** - * Sets the first day of the week. - *

- * Uses the java.util.Calendar day constants. - * - * @param day The first day of the week as a java.util.Calendar day constant. - * @see java.util.Calendar - */ - public void setFirstDayOfWeek(int day) { - firstDayOfWeek = day; - // TODO: 5/12/16 consider a less nuclear means of resetting the adapter when setting a new - // first day of week and how regular notifyDataSetChanged doesn't work (may require updating - // getItemPosition to flag current object and the ones to the left/right as changed) - CalendarPagerAdapter newAdapter; - switch (calendarMode) { - case MONTHS: - newAdapter = new MonthPagerAdapter(this); - break; - case WEEKS: - newAdapter = new WeekPagerAdapter(this); - break; - default: - throw new IllegalArgumentException("Provided display mode which is not yet implemented"); - } - if (adapter == null) { - adapter = newAdapter; - } else { - adapter = adapter.migrateStateAndReturn(newAdapter); - } - pager.setAdapter(adapter); - setRangeDates(minDate, maxDate); - - setCurrentDate( - selectionMode == SELECTION_MODE_SINGLE && !adapter.getSelectedDates().isEmpty() - ? adapter.getSelectedDates().get(0) - : CalendarDay.today()); - invalidateDecorators(); - updateUi(); - } - /** * @return The first day of the week as a {@linkplain Calendar} day constant. */ @@ -1769,4 +1652,165 @@ public void setPagingEnabled(boolean pagingEnabled) { public boolean isPagingEnabled() { return pager.isPagingEnabled(); } + + public State state() { + return state; + } + + public StateBuilder newState() { + return new StateBuilder(); + } + + public class State { + public final CalendarMode calendarMode; + public final int firstDayOfWeek; + public final CalendarDay minDate; + public final CalendarDay maxDate; + + public State(StateBuilder builder) { + calendarMode = builder.calendarMode; + firstDayOfWeek = builder.firstDayOfWeek; + minDate = builder.minDate; + maxDate = builder.maxDate; + } + + public StateBuilder edit() { + return new StateBuilder(this); + } + + } + + public class StateBuilder { + private CalendarMode calendarMode = CalendarMode.MONTHS; + private int firstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek(); + public CalendarDay minDate = null; + public CalendarDay maxDate = null; + + public StateBuilder() { + } + + private StateBuilder(final State state) { + calendarMode = state.calendarMode; + firstDayOfWeek = state.firstDayOfWeek; + minDate = state.minDate; + maxDate = state.maxDate; + } + + /** + * Sets the first day of the week. + *

+ * Uses the java.util.Calendar day constants. + * + * @param day The first day of the week as a java.util.Calendar day constant. + * @see java.util.Calendar + */ + public StateBuilder setFirstDayOfWeek(int day) { + this.firstDayOfWeek = day; + return this; + } + + /** + * Set calendar display mode. The default mode is Months. + * When switching between modes will select todays date, or the selected date, + * if selection mode is single. + * + * @param mode - calendar mode + */ + public StateBuilder setCalendarDisplayMode(CalendarMode mode) { + this.calendarMode = mode; + return this; + } + + + /** + * @param calendar set the minimum selectable date, null for no minimum + */ + public StateBuilder setMinimumDate(@Nullable Calendar calendar) { + setMinimumDate(CalendarDay.from(calendar)); + return this; + } + + /** + * @param date set the minimum selectable date, null for no minimum + */ + public StateBuilder setMinimumDate(@Nullable Date date) { + setMinimumDate(CalendarDay.from(date)); + return this; + } + + /** + * @param calendar set the minimum selectable date, null for no minimum + */ + public StateBuilder setMinimumDate(@Nullable CalendarDay calendar) { + minDate = calendar; + return this; + } + + /** + * @param calendar set the maximum selectable date, null for no maximum + */ + public StateBuilder setMaximumDate(@Nullable Calendar calendar) { + setMaximumDate(CalendarDay.from(calendar)); + return this; + } + + /** + * @param date set the maximum selectable date, null for no maximum + */ + public StateBuilder setMaximumDate(@Nullable Date date) { + setMaximumDate(CalendarDay.from(date)); + return this; + } + + /** + * @param calendar set the maximum selectable date, null for no maximum + */ + public StateBuilder setMaximumDate(@Nullable CalendarDay calendar) { + maxDate = calendar; + return this; + } + + public void commit() { + MaterialCalendarView.this.commit(new State(this)); + } + } + + private void commit(State state) { + this.state = state; + // Save states parameters + calendarMode = state.calendarMode; + firstDayOfWeek = state.firstDayOfWeek; + minDate = state.minDate; + maxDate = state.maxDate; + + // Recreate adapter + final CalendarPagerAdapter newAdapter; + switch (calendarMode) { + case MONTHS: + newAdapter = new MonthPagerAdapter(this); + break; + case WEEKS: + newAdapter = new WeekPagerAdapter(this); + break; + default: + throw new IllegalArgumentException("Provided display mode which is not yet implemented"); + } + if (adapter == null) { + adapter = newAdapter; + } else { + adapter = adapter.migrateStateAndReturn(newAdapter); + } + pager.setAdapter(adapter); + setRangeDates(minDate, maxDate); + + // Reset height params after mode change + pager.setLayoutParams(new LayoutParams(calendarMode.visibleWeeksCount + DAY_NAMES_ROW)); + + setCurrentDate( + selectionMode == SELECTION_MODE_SINGLE && !adapter.getSelectedDates().isEmpty() + ? adapter.getSelectedDates().get(0) + : CalendarDay.today()); + invalidateDecorators(); + updateUi(); + } } diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java index 66e03b87..42f2eade 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/BasicActivityDecorated.java @@ -41,14 +41,19 @@ protected void onCreate(Bundle savedInstanceState) { widget.setOnDateChangedListener(this); widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL); - Calendar calendar = Calendar.getInstance(); - widget.setSelectedDate(calendar.getTime()); + Calendar instance = Calendar.getInstance(); + widget.setSelectedDate(instance.getTime()); - calendar.set(calendar.get(Calendar.YEAR), Calendar.JANUARY, 1); - widget.setMinimumDate(calendar.getTime()); + Calendar instance1 = Calendar.getInstance(); + instance1.set(instance1.get(Calendar.YEAR), Calendar.JANUARY, 1); - calendar.set(calendar.get(Calendar.YEAR), Calendar.DECEMBER, 31); - widget.setMaximumDate(calendar.getTime()); + Calendar instance2 = Calendar.getInstance(); + instance2.set(instance2.get(Calendar.YEAR), Calendar.DECEMBER, 31); + + widget.state().edit() + .setMinimumDate(instance1.getTime()) + .setMaximumDate(instance2.getTime()) + .commit(); widget.addDecorators( new MySelectorDecorator(this), diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java index 62588674..6e2e7b6d 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/CustomizeCodeActivity.java @@ -42,10 +42,13 @@ protected void onCreate(Bundle savedInstanceState) { widget.setCurrentDate(today); widget.setSelectedDate(today); - widget.setFirstDayOfWeek(Calendar.WEDNESDAY); - widget.setMinimumDate(CalendarDay.from(2016, 4, 3)); - widget.setMaximumDate(CalendarDay.from(2016, 5, 12)); - widget.setCalendarDisplayMode(CalendarMode.WEEKS); + widget.state().edit() + .setFirstDayOfWeek(Calendar.WEDNESDAY) + .setMinimumDate(CalendarDay.from(2016, 4, 3)) + .setMaximumDate(CalendarDay.from(2016, 5, 12)) + .setCalendarDisplayMode(CalendarMode.WEEKS) + .commit(); + } } diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java index d21e9fdd..5cd59589 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DisableDaysActivity.java @@ -36,11 +36,16 @@ protected void onCreate(Bundle savedInstanceState) { Calendar calendar = Calendar.getInstance(); widget.setSelectedDate(calendar.getTime()); - calendar.set(calendar.get(Calendar.YEAR), Calendar.JANUARY, 1); - widget.setMinimumDate(calendar.getTime()); + Calendar instance1 = Calendar.getInstance(); + instance1.set(instance1.get(Calendar.YEAR), Calendar.JANUARY, 1); - calendar.set(calendar.get(Calendar.YEAR) + 2, Calendar.OCTOBER, 31); - widget.setMaximumDate(calendar.getTime()); + Calendar instance2 = Calendar.getInstance(); + instance2.set(instance2.get(Calendar.YEAR) + 2, Calendar.OCTOBER, 31); + + widget.state().edit() + .setMinimumDate(instance1.getTime()) + .setMaximumDate(instance2.getTime()) + .commit(); } private static class PrimeDayDisableDecorator implements DayViewDecorator { diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java index 06056825..373090f8 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java @@ -123,7 +123,9 @@ void onMinClicked() { showDatePickerDialog(this, widget.getMinimumDate(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { - widget.setMinimumDate(CalendarDay.from(year, monthOfYear, dayOfMonth)); + widget.state().edit() + .setMinimumDate(CalendarDay.from(year, monthOfYear, dayOfMonth)) + .commit(); } }); } @@ -133,7 +135,9 @@ void onMaxClicked() { showDatePickerDialog(this, widget.getMaximumDate(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { - widget.setMaximumDate(CalendarDay.from(year, monthOfYear, dayOfMonth)); + widget.state().edit() + .setMaximumDate(CalendarDay.from(year, monthOfYear, dayOfMonth)) + .commit(); } }); } @@ -253,17 +257,24 @@ public void onClick(DialogInterface dialog, int which) { @OnClick(R.id.button_set_first_day) void onFirstDayOfWeekClicked() { int index = random.nextInt(DAYS_OF_WEEK.length); - widget.setFirstDayOfWeek(DAYS_OF_WEEK[index]); + widget.state().edit() + .setFirstDayOfWeek(DAYS_OF_WEEK[index]) + .commit(); + } @OnClick(R.id.button_weeks) public void onSetWeekMode() { - widget.setCalendarDisplayMode(CalendarMode.WEEKS); + widget.state().edit() + .setCalendarDisplayMode(CalendarMode.WEEKS) + .commit(); } @OnClick(R.id.button_months) public void onSetMonthMode() { - widget.setCalendarDisplayMode(CalendarMode.MONTHS); + widget.state().edit() + .setCalendarDisplayMode(CalendarMode.MONTHS) + .commit(); } diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java index b1a5e81f..8cd7517f 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/SwappableBasicActivityDecorated.java @@ -37,14 +37,20 @@ protected void onCreate(Bundle savedInstanceState) { widget.setOnDateChangedListener(this); widget.setShowOtherDates(MaterialCalendarView.SHOW_ALL); - Calendar calendar = Calendar.getInstance(); - widget.setSelectedDate(calendar.getTime()); - calendar.set(calendar.get(Calendar.YEAR), Calendar.JANUARY, 1); - widget.setMinimumDate(calendar.getTime()); + Calendar instance = Calendar.getInstance(); + widget.setSelectedDate(instance.getTime()); - calendar.set(calendar.get(Calendar.YEAR), Calendar.DECEMBER, 31); - widget.setMaximumDate(calendar.getTime()); + Calendar instance1 = Calendar.getInstance(); + instance1.set(instance1.get(Calendar.YEAR), Calendar.JANUARY, 1); + + Calendar instance2 = Calendar.getInstance(); + instance2.set(instance2.get(Calendar.YEAR), Calendar.DECEMBER, 31); + + widget.state().edit() + .setMinimumDate(instance1.getTime()) + .setMaximumDate(instance2.getTime()) + .commit(); widget.addDecorators( new MySelectorDecorator(this), @@ -62,11 +68,15 @@ public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull Calend @OnClick(R.id.button_weeks) public void onSetWeekMode() { - widget.setCalendarDisplayMode(CalendarMode.WEEKS); + widget.state().edit() + .setCalendarDisplayMode(CalendarMode.WEEKS) + .commit(); } @OnClick(R.id.button_months) public void onSetMonthMode() { - widget.setCalendarDisplayMode(CalendarMode.MONTHS); + widget.state().edit() + .setCalendarDisplayMode(CalendarMode.MONTHS) + .commit(); } } From a32645b442d72bc51166ceb5e502a5c3c7bac707 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Fri, 13 May 2016 16:18:09 -0400 Subject: [PATCH 02/26] Cleanup --- .../MaterialCalendarView.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 938596d2..b27caff0 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -1049,14 +1049,18 @@ protected Parcelable onSaveInstanceState() { protected void onRestoreInstanceState(Parcelable state) { SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); + newState() + .setFirstDayOfWeek(ss.firstDayOfWeek) + .setCalendarDisplayMode(ss.calendarMode) + .setMinimumDate(ss.minDate) + .setMaximumDate(ss.maxDate) + .commit(); + setSelectionColor(ss.color); setDateTextAppearance(ss.dateTextAppearance); setWeekDayTextAppearance(ss.weekDayTextAppearance); setShowOtherDates(ss.showOtherDates); setAllowClickDaysOutsideCurrentMonth(ss.allowClickDaysOutsideCurrentMonth); - minDate = ss.minDate; - maxDate = ss.maxDate; - setRangeDates(ss.minDate, ss.maxDate); clearSelection(); for (CalendarDay calendarDay : ss.selectedDates) { setDateSelected(calendarDay, true); @@ -1067,13 +1071,6 @@ protected void onRestoreInstanceState(Parcelable state) { setSelectionMode(ss.selectionMode); setDynamicHeightEnabled(ss.dynamicHeightEnabled); setCurrentDate(ss.currentMonth); - - newState() - .setFirstDayOfWeek(ss.firstDayOfWeek) - .setCalendarDisplayMode(ss.calendarMode) - .setMinimumDate(ss.minDate) - .setMaximumDate(ss.maxDate) - .commit(); } @Override @@ -1655,10 +1652,16 @@ public boolean isPagingEnabled() { return pager.isPagingEnabled(); } + /** + * Preserve the current parameters of the Material Calendar View. + */ public State state() { return state; } + /** + * Initialize the parameters from scratch. + */ public StateBuilder newState() { return new StateBuilder(); } @@ -1676,6 +1679,9 @@ public State(StateBuilder builder) { maxDate = builder.maxDate; } + /** + * Modify parameters from current state. + */ public StateBuilder edit() { return new StateBuilder(this); } From c123024d5ba131f1ef6c16b9456c7c6566b37453 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Fri, 13 May 2016 16:21:58 -0400 Subject: [PATCH 03/26] cleanup --- .../materialcalendarview/MaterialCalendarView.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index b27caff0..4c940b6f 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -66,9 +66,6 @@ */ public class MaterialCalendarView extends ViewGroup { - static volatile State singleton = null; - private State state; - /** * {@linkplain IntDef} annotation for selection mode. * @@ -220,6 +217,8 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse private boolean allowClickDaysOutsideCurrentMonth = true; private int firstDayOfWeek; + private State state; + public MaterialCalendarView(Context context) { this(context, null); } From aa2e93fb07ed37e670639ecd5f6f9ace557b68f0 Mon Sep 17 00:00:00 2001 From: Erick C Date: Mon, 16 May 2016 13:56:05 -0400 Subject: [PATCH 04/26] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9f6dd3ad..c00f5ed7 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Major Change in 1.3.0 * Allow users to click on dates outside of current month with `setAllowClickDaysOutsideCurrentMonth` * Set tile width/height separately rather than single tile size with `setTileWidth` and `setTileHeight` * Attributes: mcv_tileWidth, mcv_tileHeight, mcv_calendarMode +* TalkBack APIs: `setContentDescriptionArrowPast`, `ArrowFuture`, `Calendar` See other changes in the [CHANGELOG](/CHANGELOG.md). From deda25ced1d6b2056ef1c9c66615f50308fd54d4 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Tue, 17 May 2016 14:43:30 -0400 Subject: [PATCH 05/26] Added travis to project --- .travis.yml | 26 ++++++++++++++++++++++++++ sample/build.gradle | 4 ++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..3713d8e3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +language: android + +jdk: + - oraclejdk7 + - oraclejdk8 + +android: + components: + - tools + - platform-tools + - build-tools-23.0.2 + - android-23 + - extra-android-m2repository + - extra-google-m2repository + +script: + - ./gradlew clean check -Dpre-dex=false + +notifications: + email: false + +sudo: false + +cache: + directories: + - $HOME/.gradle \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 11d6b179..557c9c97 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -16,8 +16,8 @@ android { dependencies { // You should use the commented out line below in you're application. // We depend on the source directly here so that development is easier. -// compile project(':library') - compile 'com.prolificinteractive:material-calendarview:1.3.0' + compile project(':library') + //compile 'com.prolificinteractive:material-calendarview:1.3.0' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:recyclerview-v7:23.4.0' From 5cf05adaf670a72d19629c321282688d0aef1bb2 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Tue, 17 May 2016 14:55:15 -0400 Subject: [PATCH 06/26] Cleanup script --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3713d8e3..ba7d6ae4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: android jdk: - - oraclejdk7 - oraclejdk8 android: @@ -14,7 +13,7 @@ android: - extra-google-m2repository script: - - ./gradlew clean check -Dpre-dex=false + - ./gradlew clean check assemble -Dpre-dex=false notifications: email: false From 3aaf78f39dbc052040827142a141e81cf3ebfac8 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Fri, 20 May 2016 11:06:56 -0400 Subject: [PATCH 07/26] Documentation updated for future release --- README.md | 2 +- docs/CUSTOMIZATION.md | 25 +++++++----------- docs/CUSTOMIZATION_BUILDER.md | 50 +++++++++++++++++++++++++++++++++++ docs/CUSTOM_SELECTORS.md | 3 ++- docs/README.md | 16 ++++++++++- sample/build.gradle | 4 +-- 6 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 docs/CUSTOMIZATION_BUILDER.md diff --git a/README.md b/README.md index c00f5ed7..bbe78b6f 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,10 @@ Example: ```xml diff --git a/docs/CUSTOMIZATION.md b/docs/CUSTOMIZATION.md index bda4995c..3dd2b201 100644 --- a/docs/CUSTOMIZATION.md +++ b/docs/CUSTOMIZATION.md @@ -3,10 +3,10 @@ Customization Options ```xml ``` @@ -34,6 +37,10 @@ If a tileSize is set, that will override the `layout_width` and `layout_height` The view is 7 tiles wide and 8 tiles high (with the top bar visible). +### Width and Height + +You also have the possibility to use `tileWidth` and `tileHeight` separately. I would recommend using either `tileSize` or, `tileWidth` and `tileHeight`. + ## Date Selection @@ -76,20 +83,6 @@ You can provide a custom color by setting `mcv_selectionColor` in xml, or by cal If you want more control than just color, you can use the [decorator api](DECORATORS.md) to set a [custom selector](CUSTOM_SELECTORS.md). -## First Day Of The Week - -The default first day of the week is Sunday. You can set a custom day of the week by setting `mcv_firstDayOfWeek` in xml, or by calling `setFirstDayOfWeek()`. -The xml attribute is an enum of `sunday` through `saturday` and `setFirstDayOfWeek()` accepts values from `java.util.Calendar` such as `Calendar.MONDAY`. - - -## Date Ranges - -By default, the calendar displays months for 200 years before today and 200 years after. -You can specify different minimum and maximum dates by calling `setMinimumDate(CalendarDay)` and `setMaximumDate(CalendarDay)`. -Passing `null` will reset back to the default 200 years. -There are also convenience methods that accept a `Calendar` or a `Date` object and convert them to a `CalendarDay` using the relevant `CalendarDay.from()` factory method. - - ## Topbar Options ### Visibility @@ -147,4 +140,4 @@ There are three different text appearances you can set: The header text appearance is used for the topbar month label. The weekday is for the row of weekday labels, and date is for the individual days. -For date text appearance, make sure you respond to presses and states. [Read more here](CUSTOM_SELECTORS.md). +For date text appearance, make sure you respond to presses and states. [Read more here](CUSTOM_SELECTORS.md). \ No newline at end of file diff --git a/docs/CUSTOMIZATION_BUILDER.md b/docs/CUSTOMIZATION_BUILDER.md new file mode 100644 index 00000000..01621101 --- /dev/null +++ b/docs/CUSTOMIZATION_BUILDER.md @@ -0,0 +1,50 @@ +State builder +============= + +Certain parameters are only modifiable using the state builder of the `MaterialCalendarView`. +Using the builder prevents from updating the view each time one of the setters is called. The view is updated when calling `Builder#commit()` and that improve performances. +Previously, the fields could be customize using casual setters. + +Here is a concrete example of how to use the builder: + +```java +mcv.state().edit() + .setFirstDayOfWeek(Calendar.WEDNESDAY) + .setMinimumDate(CalendarDay.from(2016, 4, 3)) + .setMaximumDate(CalendarDay.from(2016, 5, 12)) + .setCalendarDisplayMode(CalendarMode.WEEKS) + .commit(); +``` + +## state.edit() vs newState() + +Using `mcv.state().edit()` will preserve the current state of the `MaterialCalendarView` while `mcv.newState()` will initialize the builder with new parameters. +Only the fields that are modifiable using the builder can be reset or edit. Here is the list of the fields: + +- First Day Of Week +- Minimum Date +- Maximum Date +- Calendar Display Mode + +As an example, if you are setting `firstDayOfWeek` inside your xml, and you want to preserve the field when using the builder, you should use `state.edit()`. +However if you don't want to preserve any current parameters from the list above, use `newState()`. In most cases `state.edit()` should be the right method to use. + +### First Day Of The Week + +The default first day of the week is Sunday. You can set a custom day of the week by setting `mcv_firstDayOfWeek` in xml, or by calling `setFirstDayOfWeek()`. +The xml attribute is an enum of `sunday` through `saturday` and `setFirstDayOfWeek()` accepts values from `java.util.Calendar` such as `Calendar.MONDAY`. + + +### Date Ranges + +By default, the calendar displays months for 200 years before today and 200 years after. +You can specify different minimum and maximum dates by calling `setMinimumDate(CalendarDay)` and `setMaximumDate(CalendarDay)`. +Passing `null` will reset back to the default 200 years. +There are also convenience methods that accept a `Calendar` or a `Date` object and convert them to a `CalendarDay` using the relevant `CalendarDay.from()` factory method. + +### Calendar Display Mode + +`MaterialCalendarView` propose two display modes: weekly and monthly. You can set the display mode in your xml using the attribute `mcv_calendarMode` with `month` for monthly mode, or `week` for weekly mode. +You can also use the builder `setCalendarDisplayMode(CalendarMode)` parameter. + +It is **important** to note that the `CalendarMode.WEEKS` is still experimental. \ No newline at end of file diff --git a/docs/CUSTOM_SELECTORS.md b/docs/CUSTOM_SELECTORS.md index 679cc10a..fd0a1cab 100644 --- a/docs/CUSTOM_SELECTORS.md +++ b/docs/CUSTOM_SELECTORS.md @@ -73,7 +73,8 @@ Here's an example for a dark theme and a dark selector: - +``` +```xml diff --git a/docs/README.md b/docs/README.md index 91d4b309..ee4468d5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,6 +7,18 @@ This is where in depth documentation will be going. Check out most of the customization options [here](CUSTOMIZATION.md). +## Customization using state builder + +Some of the customization can be made using a builder. Using a builder for those parameters helps preventing bugs and improves performances. +Those parameters are: + +- [First Day Of Week](CUSTOMIZATION_BUILDER.md#first-day-of-the-week) +- [Minimum Date](CUSTOMIZATION_BUILDER.md#date-ranges) +- [Maximum Date](CUSTOMIZATION_BUILDER.md#date-ranges) +- [Calendar Display Mode](CUSTOMIZATION_BUILDER.md#calendar-display-mode) + +The documentation is available [here](CUSTOMIZATION_BUILDER.md). + ## Events, Highlighting, Custom Selectors, and More! All of this and more can be done via the decorator api. Please check out the [decorator documentation](DECORATORS.md). @@ -18,4 +30,6 @@ Check out the [documentation for custom states](CUSTOM_SELECTORS.md). ## TODO -Write and organize the documentation. Focus on customizability with real world scenarios. +- Write and organize the documentation. Focus on customization with real world scenarios. +- Improve performances. +- Add test cases. \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 11d6b179..557c9c97 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -16,8 +16,8 @@ android { dependencies { // You should use the commented out line below in you're application. // We depend on the source directly here so that development is easier. -// compile project(':library') - compile 'com.prolificinteractive:material-calendarview:1.3.0' + compile project(':library') + //compile 'com.prolificinteractive:material-calendarview:1.3.0' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:recyclerview-v7:23.4.0' From 6e915e33acec0cbb780e8627e98d0d2cb3263aef Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Fri, 20 May 2016 11:33:17 -0400 Subject: [PATCH 08/26] Update links and added entry point for documentation in Readme --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bbe78b6f..91363f69 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,11 @@ but we base it on tile size instead of an aspect ratio. The exception being that if a `tileSize` is set, that will override everything and set the view to that size. +Documentation +------------- + +Make sure to check all the documentation available [here](docs/README.md). + Customization ------------- @@ -79,11 +84,12 @@ One of the aims of this library is to be customizable. The many options include: * [Define the view's width and height in terms of tile size](docs/CUSTOMIZATION.md#tile-size) * [Single or Multiple date selection, or disabling selection entirely](docs/CUSTOMIZATION.md#date-selection) * [Showing dates from other months or those out of range](docs/CUSTOMIZATION.md#showing-other-dates) -* [Setting the first day of the week](docs/CUSTOMIZATION.md#first-day-of-the-week) -* [Show only a range of dates](docs/CUSTOMIZATION.md#date-ranges) +* [Setting the first day of the week](docs/CUSTOMIZATION_BUILDER.md#first-day-of-the-week) +* [Show only a range of dates](docs/CUSTOMIZATION_BUILDER.md#date-ranges) * [Customize the top bar](docs/CUSTOMIZATION.md#topbar-options) * [Custom labels for the header, weekdays, or individual days](docs/CUSTOMIZATION.md#custom-labels) + ### Events, Highlighting, Custom Selectors, and More! All of this and more can be done via the decorator api. Please check out the [decorator documentation](docs/DECORATORS.md). From 50380e7ec9af226757231151b72d258207e4cfcd Mon Sep 17 00:00:00 2001 From: papageorgiouk Date: Sat, 21 May 2016 00:08:42 +0300 Subject: [PATCH 09/26] Add select range functionality --- .../MaterialCalendarView.java | 74 ++++++++++++++++++- .../OnRangeSelectedListener.java | 20 +++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 81826f9b..c4455957 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -12,6 +12,7 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.util.Pair; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.SparseArray; @@ -41,6 +42,8 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; /** *

@@ -73,7 +76,7 @@ public class MaterialCalendarView extends ViewGroup { * @see #getSelectionMode() */ @Retention(RetentionPolicy.RUNTIME) - @IntDef({SELECTION_MODE_NONE, SELECTION_MODE_SINGLE, SELECTION_MODE_MULTIPLE}) + @IntDef({SELECTION_MODE_NONE, SELECTION_MODE_SINGLE, SELECTION_MODE_MULTIPLE, SELECTION_MODE_RANGE}) public @interface SelectionMode { } @@ -95,6 +98,11 @@ public class MaterialCalendarView extends ViewGroup { */ public static final int SELECTION_MODE_MULTIPLE = 2; + /** + * Selection mode which allows selection of a range between two dates + */ + public static final int SELECTION_MODE_RANGE = 3; + /** * {@linkplain IntDef} annotation for showOtherDates. * @@ -204,6 +212,8 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse private OnDateSelectedListener listener; private OnMonthChangedListener monthListener; + private OnRangeSelectedListener rangeListener; + CharSequence calendarContentDescription; private int accentColor = 0; @@ -414,6 +424,7 @@ private void updateUi() { * @see #SELECTION_MODE_NONE * @see #SELECTION_MODE_SINGLE * @see #SELECTION_MODE_MULTIPLE + * @see #SELECTION_MODE_RANGE */ public void setSelectionMode(final @SelectionMode int mode) { final @SelectionMode int oldMode = this.selectionMode; @@ -442,6 +453,10 @@ public void setSelectionMode(final @SelectionMode int mode) { } } break; + case SELECTION_MODE_RANGE: { + this.selectionMode = SELECTION_MODE_RANGE; + } + break; } adapter.setSelectionEnabled(selectionMode != SELECTION_MODE_NONE); @@ -1414,6 +1429,15 @@ public void setOnMonthChangedListener(OnMonthChangedListener listener) { this.monthListener = listener; } + /** + * Sets the listener to be notified upon a range has been selected. + * + * @param listener thing to be notified + */ + public void setOnRangeSelectedListener(OnRangeSelectedListener listener) { + this.rangeListener = listener; + } + /** * Dispatch date change events to a listener, if set * @@ -1427,6 +1451,38 @@ protected void dispatchOnDateSelected(final CalendarDay day, final boolean selec } } + /** + * Dispatch a range of days to a listener, if set + * + * @param pair the pair of days enclosing a range + */ + protected void dispatchOnRangeSelected(Pair pair) { + OnRangeSelectedListener listener = rangeListener; + List days = new ArrayList<>(); + + SortedSet sortedDays = new TreeSet<>(); + sortedDays.add(pair.first.getDate()); + sortedDays.add(pair.second.getDate()); + + Date first = sortedDays.first(); // min date + Date last = sortedDays.last(); // max date + + Calendar counter = Calendar.getInstance(); + counter.setTime(first); // start from the first day and increment + + Calendar end = Calendar.getInstance(); + end.setTime(last); // for comparison + + while (counter.before(end) || counter.equals(end)) { + days.add(CalendarDay.from(counter)); + counter.add(Calendar.DATE, 1); + } + + if (listener != null) { + listener.onRangeSelected(MaterialCalendarView.this, days); + } + } + /** * Dispatch date change events to a listener, if set * @@ -1453,6 +1509,22 @@ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) { dispatchOnDateSelected(date, nowSelected); } break; + case SELECTION_MODE_RANGE: { + adapter.setDateSelected(date, nowSelected); + if (adapter.getSelectedDates().size() > 2) { + adapter.clearSelections(); + adapter.setDateSelected(date, nowSelected); // re-set because adapter has been cleared + dispatchOnDateSelected(date, nowSelected); + } else if (adapter.getSelectedDates().size() == 2) { + List dates = adapter.getSelectedDates(); + Pair dayPair = new Pair<>(dates.get(0), dates.get(1)); + dispatchOnRangeSelected(dayPair); + } else { + adapter.setDateSelected(date, nowSelected); + dispatchOnDateSelected(date, nowSelected); + } + } + break; default: case SELECTION_MODE_SINGLE: { adapter.clearSelections(); diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java new file mode 100644 index 00000000..b157091a --- /dev/null +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java @@ -0,0 +1,20 @@ +package com.prolificinteractive.materialcalendarview; + +import android.support.annotation.NonNull; + +import java.util.List; + +/** + * The callback used to indicate a range has been selected + */ +public interface OnRangeSelectedListener { + + /** + * Called when a user selects a range of days. + * There is no logic to prevent multiple calls for the same date and state. + * + * @param widget the view associated with this listener + * @param dates the dates in the range, in ascending order + */ + void onRangeSelected(@NonNull MaterialCalendarView widget, @NonNull List dates); +} From 483e3aa75a64320c7cbc426968d7d66479f5ec8a Mon Sep 17 00:00:00 2001 From: quentin41500 Date: Sat, 21 May 2016 15:27:36 -0400 Subject: [PATCH 10/26] Cleanup, mark days between range as selected, added range in sample app --- library/build.gradle | 2 +- .../MaterialCalendarView.java | 69 ++++++++++--------- sample/build.gradle | 2 +- .../sample/DynamicSettersActivity.java | 5 +- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index 2f3b9669..8ff0ada9 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'signing' android { compileSdkVersion 23 - buildToolsVersion "23.0.2" + buildToolsVersion "23.0.3" defaultConfig { minSdkVersion 14 diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 7d3a14be..61b5ec06 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -433,35 +433,29 @@ private void updateUi() { */ public void setSelectionMode(final @SelectionMode int mode) { final @SelectionMode int oldMode = this.selectionMode; + this.selectionMode = mode; switch (mode) { - case SELECTION_MODE_MULTIPLE: { - this.selectionMode = SELECTION_MODE_MULTIPLE; - } - break; - default: - case SELECTION_MODE_SINGLE: { + case SELECTION_MODE_RANGE: + clearSelection(); + break; + case SELECTION_MODE_SINGLE: this.selectionMode = SELECTION_MODE_SINGLE; - if (oldMode == SELECTION_MODE_MULTIPLE) { + if (oldMode == SELECTION_MODE_MULTIPLE || oldMode == SELECTION_MODE_RANGE) { //We should only have one selection now, so we should pick one List dates = getSelectedDates(); if (!dates.isEmpty()) { setSelectedDate(getSelectedDate()); } } - } - break; - case SELECTION_MODE_NONE: { + break; + case SELECTION_MODE_NONE: this.selectionMode = SELECTION_MODE_NONE; if (oldMode != SELECTION_MODE_NONE) { //No selection! Clear out! clearSelection(); } - } - break; - case SELECTION_MODE_RANGE: { - this.selectionMode = SELECTION_MODE_RANGE; - } - break; + break; + default: } adapter.setSelectionEnabled(selectionMode != SELECTION_MODE_NONE); @@ -1333,27 +1327,30 @@ protected void dispatchOnDateSelected(final CalendarDay day, final boolean selec /** * Dispatch a range of days to a listener, if set * - * @param pair the pair of days enclosing a range + * @param firstDay first day enclosing a range + * @param lastDay last day enclosing a range */ - protected void dispatchOnRangeSelected(Pair pair) { - OnRangeSelectedListener listener = rangeListener; - List days = new ArrayList<>(); + protected void dispatchOnRangeSelected(final CalendarDay firstDay, final CalendarDay lastDay) { + final OnRangeSelectedListener listener = rangeListener; + final List days = new ArrayList<>(); - SortedSet sortedDays = new TreeSet<>(); - sortedDays.add(pair.first.getDate()); - sortedDays.add(pair.second.getDate()); + final SortedSet sortedDays = new TreeSet<>(); + sortedDays.add(firstDay.getDate()); + sortedDays.add(lastDay.getDate()); - Date first = sortedDays.first(); // min date - Date last = sortedDays.last(); // max date + final Date first = sortedDays.first(); // min date + final Date last = sortedDays.last(); // max date - Calendar counter = Calendar.getInstance(); + final Calendar counter = Calendar.getInstance(); counter.setTime(first); // start from the first day and increment - Calendar end = Calendar.getInstance(); + final Calendar end = Calendar.getInstance(); end.setTime(last); // for comparison while (counter.before(end) || counter.equals(end)) { - days.add(CalendarDay.from(counter)); + final CalendarDay current = CalendarDay.from(counter); + adapter.setDateSelected(current, true); + days.add(current); counter.add(Calendar.DATE, 1); } @@ -1395,9 +1392,8 @@ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) { adapter.setDateSelected(date, nowSelected); // re-set because adapter has been cleared dispatchOnDateSelected(date, nowSelected); } else if (adapter.getSelectedDates().size() == 2) { - List dates = adapter.getSelectedDates(); - Pair dayPair = new Pair<>(dates.get(0), dates.get(1)); - dispatchOnRangeSelected(dayPair); + final List dates = adapter.getSelectedDates(); + dispatchOnRangeSelected(dates.get(0), dates.get(1)); } else { adapter.setDateSelected(date, nowSelected); dispatchOnDateSelected(date, nowSelected); @@ -1414,6 +1410,17 @@ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) { } } + /** + * Select a fresh range of date including first day and last day. + * + * @param firstDay first day of the range to select + * @param lastDay last day of the range to select + */ + public void selectRange(final CalendarDay firstDay, final CalendarDay lastDay) { + clearSelection(); + dispatchOnRangeSelected(firstDay, lastDay); + } + /** * Call by {@link CalendarPagerView} to indicate that a day was clicked and we should handle it * diff --git a/sample/build.gradle b/sample/build.gradle index 557c9c97..03cab093 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion "23.0.2" + buildToolsVersion "23.0.3" defaultConfig { applicationId "com.prolificinteractive.materialcalendarview.sample" diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java index 373090f8..5f6ac2df 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java @@ -147,7 +147,7 @@ void onSelectedClicked() { showDatePickerDialog(this, widget.getSelectedDate(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { - widget.setSelectedDate(CalendarDay.from(year, monthOfYear, dayOfMonth)); + widget.selectRange(CalendarDay.from(2016, 4, 26), CalendarDay.from(2016, 5, 10)); } }); } @@ -230,7 +230,8 @@ void onChangeSelectionMode() { CharSequence[] items = { "No Selection", "Single Date", - "Multiple Dates" + "Multiple Dates", + "Range of Dates" }; new AlertDialog.Builder(this) .setTitle("Selection Mode") From 3e497f1228d92a62f0f764dd8116106ff2669829 Mon Sep 17 00:00:00 2001 From: quentin41500 Date: Sat, 21 May 2016 15:37:43 -0400 Subject: [PATCH 11/26] Cleanup --- .../materialcalendarview/MaterialCalendarView.java | 9 +++++---- .../sample/DynamicSettersActivity.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 61b5ec06..c8b1a68b 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -423,7 +423,8 @@ private void updateUi() { * Change the selection mode of the calendar. The default mode is {@linkplain #SELECTION_MODE_SINGLE} * * @param mode the selection mode to change to. This must be one of - * {@linkplain #SELECTION_MODE_NONE}, {@linkplain #SELECTION_MODE_SINGLE}, or {@linkplain #SELECTION_MODE_MULTIPLE}. + * {@linkplain #SELECTION_MODE_NONE}, {@linkplain #SELECTION_MODE_SINGLE}, + * {@linkplain #SELECTION_MODE_RANGE} or {@linkplain #SELECTION_MODE_MULTIPLE}. * Unknown values will act as {@linkplain #SELECTION_MODE_SINGLE} * @see #getSelectionMode() * @see #SELECTION_MODE_NONE @@ -439,7 +440,6 @@ public void setSelectionMode(final @SelectionMode int mode) { clearSelection(); break; case SELECTION_MODE_SINGLE: - this.selectionMode = SELECTION_MODE_SINGLE; if (oldMode == SELECTION_MODE_MULTIPLE || oldMode == SELECTION_MODE_RANGE) { //We should only have one selection now, so we should pick one List dates = getSelectedDates(); @@ -448,6 +448,7 @@ public void setSelectionMode(final @SelectionMode int mode) { } } break; + default: case SELECTION_MODE_NONE: this.selectionMode = SELECTION_MODE_NONE; if (oldMode != SELECTION_MODE_NONE) { @@ -455,7 +456,6 @@ public void setSelectionMode(final @SelectionMode int mode) { clearSelection(); } break; - default: } adapter.setSelectionEnabled(selectionMode != SELECTION_MODE_NONE); @@ -491,6 +491,7 @@ public void goToNext() { * @see #SELECTION_MODE_NONE * @see #SELECTION_MODE_SINGLE * @see #SELECTION_MODE_MULTIPLE + * @see #SELECTION_MODE_RANGE */ @SelectionMode public int getSelectionMode() { @@ -1414,7 +1415,7 @@ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) { * Select a fresh range of date including first day and last day. * * @param firstDay first day of the range to select - * @param lastDay last day of the range to select + * @param lastDay last day of the range to select */ public void selectRange(final CalendarDay firstDay, final CalendarDay lastDay) { clearSelection(); diff --git a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java index 5f6ac2df..cdb4d310 100644 --- a/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java +++ b/sample/src/main/java/com/prolificinteractive/materialcalendarview/sample/DynamicSettersActivity.java @@ -147,7 +147,7 @@ void onSelectedClicked() { showDatePickerDialog(this, widget.getSelectedDate(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { - widget.selectRange(CalendarDay.from(2016, 4, 26), CalendarDay.from(2016, 5, 10)); + widget.setSelectedDate(CalendarDay.from(year, monthOfYear, dayOfMonth)); } }); } From c0512d4e2ed0969f699b953d655b20726e4301e6 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Mon, 23 May 2016 10:51:20 -0400 Subject: [PATCH 12/26] Update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ba7d6ae4..58dddcf7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ android: components: - tools - platform-tools - - build-tools-23.0.2 + - build-tools-23.0.3 - android-23 - extra-android-m2repository - extra-google-m2repository From 4fddc65f7328d5907af6fe93485a1c5fbec7720d Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Mon, 23 May 2016 14:27:11 -0400 Subject: [PATCH 13/26] Cleanup --- .../MaterialCalendarView.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index c8b1a68b..05635f4c 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -12,7 +12,6 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.util.Pair; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.SparseArray; @@ -42,8 +41,6 @@ import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.SortedSet; -import java.util.TreeSet; /** *

@@ -439,6 +436,8 @@ public void setSelectionMode(final @SelectionMode int mode) { case SELECTION_MODE_RANGE: clearSelection(); break; + case SELECTION_MODE_MULTIPLE: + break; case SELECTION_MODE_SINGLE: if (oldMode == SELECTION_MODE_MULTIPLE || oldMode == SELECTION_MODE_RANGE) { //We should only have one selection now, so we should pick one @@ -1201,7 +1200,7 @@ public int getFirstDayOfWeek() { /** * By default, the calendar will take up all the space needed to show any month (6 rows). * By enabling dynamic height, the view will change height dependant on the visible month. - *

+ *

* This means months that only need 5 or 4 rows to show the entire month will only take up * that many rows, and will grow and shrink as necessary. * @@ -1326,7 +1325,7 @@ protected void dispatchOnDateSelected(final CalendarDay day, final boolean selec } /** - * Dispatch a range of days to a listener, if set + * Dispatch a range of days to a listener, if set. First day must be before last Day. * * @param firstDay first day enclosing a range * @param lastDay last day enclosing a range @@ -1335,18 +1334,11 @@ protected void dispatchOnRangeSelected(final CalendarDay firstDay, final Calenda final OnRangeSelectedListener listener = rangeListener; final List days = new ArrayList<>(); - final SortedSet sortedDays = new TreeSet<>(); - sortedDays.add(firstDay.getDate()); - sortedDays.add(lastDay.getDate()); - - final Date first = sortedDays.first(); // min date - final Date last = sortedDays.last(); // max date - final Calendar counter = Calendar.getInstance(); - counter.setTime(first); // start from the first day and increment + counter.setTime(firstDay.getDate()); // start from the first day and increment final Calendar end = Calendar.getInstance(); - end.setTime(last); // for comparison + end.setTime(lastDay.getDate()); // for comparison while (counter.before(end) || counter.equals(end)) { final CalendarDay current = CalendarDay.from(counter); @@ -1394,7 +1386,11 @@ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) { dispatchOnDateSelected(date, nowSelected); } else if (adapter.getSelectedDates().size() == 2) { final List dates = adapter.getSelectedDates(); - dispatchOnRangeSelected(dates.get(0), dates.get(1)); + if (dates.get(0).isAfter(dates.get(1))) { + dispatchOnRangeSelected(dates.get(1), dates.get(0)); + } else { + dispatchOnRangeSelected(dates.get(0), dates.get(1)); + } } else { adapter.setDateSelected(date, nowSelected); dispatchOnDateSelected(date, nowSelected); @@ -1419,7 +1415,11 @@ protected void onDateClicked(@NonNull CalendarDay date, boolean nowSelected) { */ public void selectRange(final CalendarDay firstDay, final CalendarDay lastDay) { clearSelection(); - dispatchOnRangeSelected(firstDay, lastDay); + if (firstDay.isAfter(lastDay)) { + dispatchOnRangeSelected(lastDay, firstDay); + } else { + dispatchOnRangeSelected(firstDay, lastDay); + } } /** @@ -1786,7 +1786,7 @@ private StateBuilder(final State state) { /** * Sets the first day of the week. - *

+ *

* Uses the java.util.Calendar day constants. * * @param day The first day of the week as a java.util.Calendar day constant. From 3800a6ca9b9ca2754eef90bb0edc09cbf773ae42 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Mon, 23 May 2016 19:00:05 -0400 Subject: [PATCH 14/26] Update CUSTOMIZATION.md --- docs/CUSTOMIZATION.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/CUSTOMIZATION.md b/docs/CUSTOMIZATION.md index 3dd2b201..a6182362 100644 --- a/docs/CUSTOMIZATION.md +++ b/docs/CUSTOMIZATION.md @@ -44,12 +44,12 @@ You also have the possibility to use `tileWidth` and `tileHeight` separately. I ## Date Selection -We support three modes of selection: single, multiple, or none. The default is single selection. -The mode can be changed by calling `setSelectionMode()` and passing the appropriate constant (`SELECTION_MODE_NONE`, `SELECTION_MODE_SINGLE`, or `SELECTION_MODE_MULTIPLE`). +We support four modes of selection: single, multiple, range or none. The default is single selection. +The mode can be changed by calling `setSelectionMode()` and passing the appropriate constant (`SELECTION_MODE_NONE`, `SELECTION_MODE_SINGLE`, `SELECTION_MODE_RANGE` or `SELECTION_MODE_MULTIPLE`). If you change to single selection, all selected days except the last selected will be cleared. -If you change to none, all selected days will be cleared. +If you change to none or range, all selected days will be cleared. -You can set an `OnDateSelectedListener` to listen for selections, make sure to take into account multiple calls for the same date and state. +You can set an `OnDateSelectedListener` to listen for selections, make sure to take into account multiple calls for the same date and state. In case of range selection, use `OnRangeSelectedListener` which returns the list of date from the range including first and last. You can manually select or deselect dates by calling `setDateSelected()`. Use `setSelectedDate()` to clear the current selection(s) and select the provided date. @@ -140,4 +140,4 @@ There are three different text appearances you can set: The header text appearance is used for the topbar month label. The weekday is for the row of weekday labels, and date is for the individual days. -For date text appearance, make sure you respond to presses and states. [Read more here](CUSTOM_SELECTORS.md). \ No newline at end of file +For date text appearance, make sure you respond to presses and states. [Read more here](CUSTOM_SELECTORS.md). From 83533f80400d882bd8df9b7ad5656945b27b1f95 Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Tue, 24 May 2016 13:12:38 -0400 Subject: [PATCH 15/26] Update changelog and gradle properties for upcoming release --- CHANGELOG.md | 8 +++++++- gradle.properties | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce26043e..ac9203f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ Change Log ========== +Version 1.4.0 *(TBD)* +---------------------------- +* New: Add select range functionality. Use `setSelectionMode(MaterialCalendarView.SELECTION_MODE_RANGE)` and `setOnRangeSelectedListener` +* Breaking Change: `setFirstDayOfWeek`, `setMin/MaxDate`, and `setCalendarDisplayMode` are moved to a `State` object. Call `mcv.state().edit()` to edit them and commit the changes with `commit`. See [CUSTOMIZATION_BUILDER](docs/CUSTOMIZATION_BUILDER.md) for usage details. +* Change: Updated documentation regarding 1.3.0 additions + Version 1.3.0 *(2016-05-16)* ---------------------------- @@ -69,7 +75,7 @@ where the view will try and take up as much space as necessary, but we base it on tile size instead of an aspect ratio. The exception being that if a `tileSize` is set, that will override everything and set the view to that size. -* Fix: Use more efficent method for indexing months +* Fix: Use more efficient method for indexing months Version 0.7.0 *(2015-07-09)* ---------------------------- diff --git a/gradle.properties b/gradle.properties index 9481178d..712c03c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,8 +18,8 @@ # org.gradle.parallel=true GROUP=com.prolificinteractive -VERSION_NAME=1.3.0 -VERSION_CODE=14 +VERSION_NAME=1.4.0-SNAPSHOT +VERSION_CODE=15 POM_PACKAGING=aar POM_NAME=Material CalendarView From 9890fefc0d624ab677e0ff0a7ec91e8bcfa2b891 Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Tue, 24 May 2016 14:04:02 -0400 Subject: [PATCH 16/26] Update README with 1.4 changes --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 91363f69..e9fb8c77 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,25 @@ Example: marked `@Experimental` are subject to change quickly and should not be used in production code. They are allowed for testing and feedback. +Major Change in 1.4.0 +--------------------- +* Breaking Change: `setFirstDayOfWeek`, `setMin/MaxDate`, and `setCalendarDisplayMode` are moved to a `State` object. This was necessary because it was unclear that these were not simple setters--individually, they were side effecting and triggered full adapter/date range recalculations. Typical usage of the view involves setting all these invariants up front during `onCreate` and it was unknown to the user that setting all 4 of these would create a lot of waste. Not to mention certain things were side effecting--some would reset the current day or selected date. As a result, the same 4 methods called in a different order could result in a different state, which is bad. + + For most cases you will simply need to replace setting those invariants with: + ```java + mcv.state().edit() + .setFirstDayOfWeek(Calendar.WEDNESDAY) + .setMinimumDate(CalendarDay.from(2016, 4, 3)) + .setMaximumDate(CalendarDay.from(2016, 5, 12)) + .setCalendarDisplayMode(CalendarMode.WEEKS) + .commit(); + ``` + + `mcv.state().edit()` will retain previously set values; `mcv.newState()` will create a new state using default values. Calling `commit` will trigger the rebuild of adapters and date ranges. It is recommended these state changes occur as the first modification to MCV (before configuring anything else like current date or selected date); we make no guarantee those modifications will be retained when the state is modified. + + See [CUSTOMIZATION_BUILDER](docs/CUSTOMIZATION_BUILDER.md) for usage details. +* New: `setSelectionMode(SELECTION_MODE_RANGE)` was added to allow 2 dates to be selected and have the entire range of dates selected. Much thanks to [papageorgiouk](https://github.com/papageorgiouk) for his work on this feature. + Major Change in 1.3.0 --------------------- * Breaking change: `getTileSize` is deprecated. Use `getTileWidth` or `getTileHeight`. From b4566700594a374369170c6fe4827f4a95e82a1e Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Wed, 25 May 2016 10:58:17 -0400 Subject: [PATCH 17/26] Change DateFormatTitleFormatter to use LLLL instead of MMMM for month formatting (needed for some context aware languages) --- .../materialcalendarview/format/DateFormatTitleFormatter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java index 3e1de558..b7eeae11 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/format/DateFormatTitleFormatter.java @@ -14,11 +14,11 @@ public class DateFormatTitleFormatter implements TitleFormatter { private final DateFormat dateFormat; /** - * Format using "MMMM yyyy" for formatting + * Format using "LLLL yyyy" for formatting */ public DateFormatTitleFormatter() { this.dateFormat = new SimpleDateFormat( - "MMMM yyyy", Locale.getDefault() + "LLLL yyyy", Locale.getDefault() ); } From 075f5f67548c38ac3e036c0dcd637a93b371205d Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Thu, 26 May 2016 08:39:13 -0400 Subject: [PATCH 18/26] Incorrect min date used when calculating num week difference --- .../materialcalendarview/WeekPagerAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java index a1ab577b..85b12bc8 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java @@ -42,7 +42,7 @@ public static class Weekly implements DateRangeIndex { public Weekly(@NonNull CalendarDay min, @NonNull CalendarDay max, int firstDayOfWeek) { this.min = getFirstDayOfWeek(min, firstDayOfWeek); - this.count = weekNumberDifference(min, max) + 1; + this.count = weekNumberDifference(this.min, max) + 1; } @Override From 70183cd73308a3e39c1e5980f9683a83e737b73e Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Thu, 26 May 2016 10:34:45 -0400 Subject: [PATCH 19/26] Shields update --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f6dd3ad..cd3d87a8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -Material Calendar View [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Material%20Calendar%20View-blue.svg?style=flat)](https://android-arsenal.com/details/1/1531) +Material Calendar View ====================== +[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Material%20Calendar%20View-blue.svg?style=flat)](https://android-arsenal.com/details/1/1531) [![Maven Central](https://img.shields.io/maven-central/v/com.prolificinteractive/material-calendarview.svg?maxAge=2592000)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22material-calendarview%22) A Material design back port of Android's CalendarView. The goal is to have a Material look and feel, rather than 100% parity with the platform's implementation. From 77d025796c08dddcca8b5db3c44c27a0fa6a2bd7 Mon Sep 17 00:00:00 2001 From: Quentin Colle Date: Thu, 26 May 2016 10:38:04 -0400 Subject: [PATCH 20/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd3d87a8..da9e40d6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Material Calendar View ====================== -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Material%20Calendar%20View-blue.svg?style=flat)](https://android-arsenal.com/details/1/1531) [![Maven Central](https://img.shields.io/maven-central/v/com.prolificinteractive/material-calendarview.svg?maxAge=2592000)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22material-calendarview%22) +[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Material%20Calendar%20View-blue.svg?style=flat)](https://android-arsenal.com/details/1/1531) [![Maven Central](https://img.shields.io/maven-central/v/com.prolificinteractive/material-calendarview.svg?maxAge=2592000)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22material-calendarview%22) [![Travis branch](https://img.shields.io/travis/prolificinteractive/material-calendarview.svg?maxAge=2592000)](https://travis-ci.org/prolificinteractive/material-calendarview) A Material design back port of Android's CalendarView. The goal is to have a Material look and feel, rather than 100% parity with the platform's implementation. From 53a83fd48214a2f5bfeacf1d02b3a62f7b6dc0b4 Mon Sep 17 00:00:00 2001 From: Igor Levaja Date: Mon, 30 May 2016 15:39:02 +0200 Subject: [PATCH 21/26] Fix for an issue when a wrong week is selected when switching between month and week display mode. Refs #222 --- .../materialcalendarview/WeekPagerAdapter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java index 85b12bc8..62f77ebf 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/WeekPagerAdapter.java @@ -67,7 +67,11 @@ public CalendarDay getItem(int position) { private int weekNumberDifference(@NonNull CalendarDay min, @NonNull CalendarDay max) { long millisDiff = max.getDate().getTime() - min.getDate().getTime(); - long dayDiff = TimeUnit.DAYS.convert(millisDiff, TimeUnit.MILLISECONDS); + + int dstOffsetMax = max.getCalendar().get(Calendar.DST_OFFSET); + int dstOffsetMin = min.getCalendar().get(Calendar.DST_OFFSET); + + long dayDiff = TimeUnit.DAYS.convert(millisDiff + dstOffsetMax - dstOffsetMin, TimeUnit.MILLISECONDS); return (int) (dayDiff / DAYS_IN_WEEK); } From 21f239e8570e556d483a2f1bb828a6ccf6ed3137 Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Tue, 31 May 2016 12:29:39 -0400 Subject: [PATCH 22/26] Fix current month not updating if min date is set to a month after the current month --- .../materialcalendarview/MaterialCalendarView.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 05635f4c..9742b725 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -1095,6 +1095,9 @@ private void setRangeDates(CalendarDay min, CalendarDay max) { CalendarDay c = currentMonth; adapter.setRangeDates(min, max); currentMonth = c; + if (min != null) { + currentMonth = min.isAfter(currentMonth) ? min : currentMonth; + } int position = adapter.getIndexForDay(c); pager.setCurrentItem(position, false); updateUi(); From 657485999083b7f77c7c6c6214d2230a3a09bb40 Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Wed, 1 Jun 2016 10:37:55 -0400 Subject: [PATCH 23/26] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac9203f2..c4fb09ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Version 1.4.0 *(TBD)* * New: Add select range functionality. Use `setSelectionMode(MaterialCalendarView.SELECTION_MODE_RANGE)` and `setOnRangeSelectedListener` * Breaking Change: `setFirstDayOfWeek`, `setMin/MaxDate`, and `setCalendarDisplayMode` are moved to a `State` object. Call `mcv.state().edit()` to edit them and commit the changes with `commit`. See [CUSTOMIZATION_BUILDER](docs/CUSTOMIZATION_BUILDER.md) for usage details. * Change: Updated documentation regarding 1.3.0 additions +* Fix: Current month and title pager updates correctly if minDate is set after the current month +* Fix: Week number difference calculation correctly accounts for DST offsets. Thanks Igor Levaja! +* Fix: Date formatter uses L instead of M for month (standalone instead of context sensitive) Version 1.3.0 *(2016-05-16)* ---------------------------- From 4e0dc750ad2f6a71a4822afa179e10f9b2fc7068 Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Wed, 1 Jun 2016 10:39:58 -0400 Subject: [PATCH 24/26] Prepare for release --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 712c03c3..5a024e4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ # org.gradle.parallel=true GROUP=com.prolificinteractive -VERSION_NAME=1.4.0-SNAPSHOT +VERSION_NAME=1.4.0 VERSION_CODE=15 POM_PACKAGING=aar From 98262a92cf775838f27d04b21b45108c06a44fc4 Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Wed, 1 Jun 2016 10:44:24 -0400 Subject: [PATCH 25/26] Update README --- README.md | 4 ++-- .../materialcalendarview/MaterialCalendarView.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index de97d74d..00177d42 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ Major Change in 1.4.0 See [CUSTOMIZATION_BUILDER](docs/CUSTOMIZATION_BUILDER.md) for usage details. * New: `setSelectionMode(SELECTION_MODE_RANGE)` was added to allow 2 dates to be selected and have the entire range of dates selected. Much thanks to [papageorgiouk](https://github.com/papageorgiouk) for his work on this feature. +See other changes in the [CHANGELOG](/CHANGELOG.md). + Major Change in 1.3.0 --------------------- * Breaking change: `getTileSize` is deprecated. Use `getTileWidth` or `getTileHeight`. @@ -64,8 +66,6 @@ Major Change in 1.3.0 * Attributes: mcv_tileWidth, mcv_tileHeight, mcv_calendarMode * TalkBack APIs: `setContentDescriptionArrowPast`, `ArrowFuture`, `Calendar` -See other changes in the [CHANGELOG](/CHANGELOG.md). - Major Change in 1.2.0 --------------------- You can now collapse the calendar view to single week paging by calling diff --git a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java index 05635f4c..9742b725 100644 --- a/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java +++ b/library/src/main/java/com/prolificinteractive/materialcalendarview/MaterialCalendarView.java @@ -1095,6 +1095,9 @@ private void setRangeDates(CalendarDay min, CalendarDay max) { CalendarDay c = currentMonth; adapter.setRangeDates(min, max); currentMonth = c; + if (min != null) { + currentMonth = min.isAfter(currentMonth) ? min : currentMonth; + } int position = adapter.getIndexForDay(c); pager.setCurrentItem(position, false); updateUi(); From 0bab6279ebd20426168d468ecd157fad1b900e3a Mon Sep 17 00:00:00 2001 From: Erick Chang Date: Wed, 1 Jun 2016 11:45:31 -0400 Subject: [PATCH 26/26] Update README/build.gradle to reference 1.4.0 --- README.md | 2 +- sample/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 00177d42..a94c4d1c 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ and feel, rather than 100% parity with the platform's implementation. Usage ----- -1. Add `compile 'com.prolificinteractive:material-calendarview:1.3.0'` to your dependencies. +1. Add `compile 'com.prolificinteractive:material-calendarview:1.4.0'` to your dependencies. 2. Add `MaterialCalendarView` into your layouts or view hierarchy. 3. Set a `OnDateSelectedListener` or call `MaterialCalendarView.getSelectedDates()` when you need it. diff --git a/sample/build.gradle b/sample/build.gradle index 03cab093..5d6be7e2 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -17,7 +17,7 @@ dependencies { // You should use the commented out line below in you're application. // We depend on the source directly here so that development is easier. compile project(':library') - //compile 'com.prolificinteractive:material-calendarview:1.3.0' + //compile 'com.prolificinteractive:material-calendarview:1.4.0' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.android.support:recyclerview-v7:23.4.0'