-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Final - Select range #315
Merged
+123
−21
Merged
Final - Select range #315
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
36cf970
Fix issue with arrow not enable when setting maxDate
108ca59
Merge pull request #284 from prolificinteractive/arrow_enable
ekchang cb03a86
Merge pull request #303 from prolificinteractive/future-1.x
ekchang 50380e7
Add select range functionality
papageorgiouk 2ce7551
Merge branch 'range-select' of https://github.com/papageorgiouk/mater…
483e3aa
Cleanup, mark days between range as selected, added range in sample app
3e497f1
Cleanup
c0512d4
Update travis
4fddc65
Cleanup
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
||
/** | ||
* <p> | ||
|
@@ -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; | ||
|
@@ -413,40 +423,39 @@ 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 | ||
* @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; | ||
this.selectionMode = mode; | ||
switch (mode) { | ||
case SELECTION_MODE_MULTIPLE: { | ||
this.selectionMode = SELECTION_MODE_MULTIPLE; | ||
} | ||
break; | ||
default: | ||
case SELECTION_MODE_SINGLE: { | ||
this.selectionMode = SELECTION_MODE_SINGLE; | ||
if (oldMode == SELECTION_MODE_MULTIPLE) { | ||
case SELECTION_MODE_RANGE: | ||
clearSelection(); | ||
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 | ||
List<CalendarDay> dates = getSelectedDates(); | ||
if (!dates.isEmpty()) { | ||
setSelectedDate(getSelectedDate()); | ||
} | ||
} | ||
} | ||
break; | ||
case SELECTION_MODE_NONE: { | ||
break; | ||
default: | ||
case SELECTION_MODE_NONE: | ||
this.selectionMode = SELECTION_MODE_NONE; | ||
if (oldMode != SELECTION_MODE_NONE) { | ||
//No selection! Clear out! | ||
clearSelection(); | ||
} | ||
} | ||
break; | ||
break; | ||
} | ||
|
||
adapter.setSelectionEnabled(selectionMode != SELECTION_MODE_NONE); | ||
|
@@ -482,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() { | ||
|
@@ -1088,6 +1098,7 @@ private void setRangeDates(CalendarDay min, CalendarDay max) { | |
currentMonth = c; | ||
int position = adapter.getIndexForDay(c); | ||
pager.setCurrentItem(position, false); | ||
updateUi(); | ||
} | ||
|
||
public static class SavedState extends BaseSavedState { | ||
|
@@ -1292,6 +1303,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 | ||
* | ||
|
@@ -1305,6 +1325,41 @@ protected void dispatchOnDateSelected(final CalendarDay day, final boolean selec | |
} | ||
} | ||
|
||
/** | ||
* Dispatch a range of days to a listener, if set | ||
* | ||
* @param firstDay first day enclosing a range | ||
* @param lastDay last day enclosing a range | ||
*/ | ||
protected void dispatchOnRangeSelected(final CalendarDay firstDay, final CalendarDay lastDay) { | ||
final OnRangeSelectedListener listener = rangeListener; | ||
final List<CalendarDay> days = new ArrayList<>(); | ||
|
||
final SortedSet<Date> sortedDays = new TreeSet<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sort is unnecessary--we only have two dates. If first day is after last day, call the method again with inverted params:
|
||
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 | ||
|
||
final Calendar end = Calendar.getInstance(); | ||
end.setTime(last); // for comparison | ||
|
||
while (counter.before(end) || counter.equals(end)) { | ||
final CalendarDay current = CalendarDay.from(counter); | ||
adapter.setDateSelected(current, true); | ||
days.add(current); | ||
counter.add(Calendar.DATE, 1); | ||
} | ||
|
||
if (listener != null) { | ||
listener.onRangeSelected(MaterialCalendarView.this, days); | ||
} | ||
} | ||
|
||
/** | ||
* Dispatch date change events to a listener, if set | ||
* | ||
|
@@ -1331,6 +1386,21 @@ 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) { | ||
final List<CalendarDay> dates = adapter.getSelectedDates(); | ||
dispatchOnRangeSelected(dates.get(0), dates.get(1)); | ||
} else { | ||
adapter.setDateSelected(date, nowSelected); | ||
dispatchOnDateSelected(date, nowSelected); | ||
} | ||
} | ||
break; | ||
default: | ||
case SELECTION_MODE_SINGLE: { | ||
adapter.clearSelections(); | ||
|
@@ -1341,6 +1411,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 | ||
* | ||
|
20 changes: 20 additions & 0 deletions
20
...y/src/main/java/com/prolificinteractive/materialcalendarview/OnRangeSelectedListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<CalendarDay> dates); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SELECTION_MODE_MULTIPLE
shouldn't be removed, this is breaking selection mode multiple