Skip to content

Commit a9b6f94

Browse files
author
Jens Claes
committed
Merge branch 'iss58-dynamic-prefetch-range' into quivr-master
Conflicts: library/src/main/java/com/alamkanak/weekview/WeekView.java
2 parents e8a9db4 + e56c1f4 commit a9b6f94

File tree

3 files changed

+123
-77
lines changed

3 files changed

+123
-77
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.alamkanak.weekview;
2+
3+
import java.util.Calendar;
4+
import java.util.List;
5+
6+
public class MonthLoader implements WeekViewLoader {
7+
8+
private WeekView.MonthChangeListener mOnMonthChangeListener;
9+
public MonthLoader(WeekView.MonthChangeListener listener){
10+
this.mOnMonthChangeListener = listener;
11+
}
12+
13+
@Override
14+
public double toWeekViewPeriodIndex(Calendar instance){
15+
return instance.get(Calendar.YEAR)*12 + instance.get(Calendar.MONTH) + (instance.get(Calendar.DAY_OF_MONTH)-1)/30.0;
16+
}
17+
18+
@Override
19+
public List<WeekViewEvent> onLoad(int periodIndex){
20+
return mOnMonthChangeListener.onMonthChange(periodIndex/12,periodIndex%12+1);
21+
}
22+
23+
24+
public WeekView.MonthChangeListener getOnMonthChangeListener() {
25+
return mOnMonthChangeListener;
26+
}
27+
28+
public void setOnMonthChangeListener(WeekView.MonthChangeListener onMonthChangeListener) {
29+
this.mOnMonthChangeListener = onMonthChangeListener;
30+
}
31+
}

library/src/main/java/com/alamkanak/weekview/WeekView.java

Lines changed: 69 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,13 @@ public class WeekView extends View {
7070
private Paint mEventBackgroundPaint;
7171
private float mHeaderColumnWidth;
7272
private List<EventRect> mEventRects;
73+
private List<WeekViewEvent> mPreviousPeriodEvents;
74+
private List<WeekViewEvent> mCurrentPeriodEvents;
75+
private List<WeekViewEvent> mNextPeriodEvents;
7376
private TextPaint mEventTextPaint;
7477
private Paint mHeaderColumnBackgroundPaint;
7578
private Scroller mStickyScroller;
76-
private int mFetchedMonths[] = new int[3];
79+
private int mFetchedPeriod = -1; // the middle period the calendar has fetched.
7780
private boolean mRefreshEvents = false;
7881
private float mDistanceY = 0;
7982
private float mDistanceX = 0;
@@ -126,7 +129,7 @@ public class WeekView extends View {
126129
// Listeners.
127130
private EventClickListener mEventClickListener;
128131
private EventLongPressListener mEventLongPressListener;
129-
private MonthChangeListener mMonthChangeListener;
132+
private WeekViewLoader mWeekViewLoader;
130133
private EmptyViewClickListener mEmptyViewClickListener;
131134
private EmptyViewLongPressListener mEmptyViewLongPressListener;
132135
private DateTimeInterpreter mDateTimeInterpreter;
@@ -531,7 +534,9 @@ private void drawHeaderRowAndEvents(Canvas canvas) {
531534

532535
// Get more events if necessary. We want to store the events 3 months beforehand. Get
533536
// events only when it is the first iteration of the loop.
534-
if (mEventRects == null || mRefreshEvents || (dayNumber == leftDaysWithGaps + 1 && mFetchedMonths[1] != day.get(Calendar.MONTH)+1 && day.get(Calendar.DAY_OF_MONTH) == 15)) {
537+
if (mEventRects == null || mRefreshEvents ||
538+
(dayNumber == leftDaysWithGaps + 1 && mFetchedPeriod != (int) mWeekViewLoader.toWeekViewPeriodIndex(day) &&
539+
Math.abs(mFetchedPeriod - mWeekViewLoader.toWeekViewPeriodIndex(day)) > 0.5)) {
535540
getMoreEvents(day);
536541
mRefreshEvents = false;
537542
}
@@ -785,59 +790,60 @@ public EventRect(WeekViewEvent event, WeekViewEvent originalEvent, RectF rectF)
785790
* @param day The day where the user is currently is.
786791
*/
787792
private void getMoreEvents(Calendar day) {
788-
789-
// Delete all events if its not current month +- 1.
790-
deleteFarMonths(day);
791-
792793
// Get more events if the month is changed.
793794
if (mEventRects == null)
794795
mEventRects = new ArrayList<EventRect>();
795-
if (mMonthChangeListener == null && !isInEditMode())
796+
if (mWeekViewLoader == null && !isInEditMode())
796797
throw new IllegalStateException("You must provide a MonthChangeListener");
797798

798799
// If a refresh was requested then reset some variables.
799800
if (mRefreshEvents) {
800801
mEventRects.clear();
801-
mFetchedMonths = new int[3];
802-
}
803-
804-
// Get events of previous month.
805-
int previousMonth = (day.get(Calendar.MONTH) == 0?12:day.get(Calendar.MONTH));
806-
int nextMonth = (day.get(Calendar.MONTH)+2 == 13 ?1:day.get(Calendar.MONTH)+2);
807-
int[] lastFetchedMonth = mFetchedMonths.clone();
808-
if (mFetchedMonths[0] < 1 || mFetchedMonths[0] != previousMonth || mRefreshEvents) {
809-
if (!containsValue(lastFetchedMonth, previousMonth) && !isInEditMode()){
810-
List<WeekViewEvent> events = mMonthChangeListener.onMonthChange((previousMonth==12)?day.get(Calendar.YEAR)-1:day.get(Calendar.YEAR), previousMonth);
811-
sortEvents(events);
812-
for (WeekViewEvent event: events) {
813-
cacheEvent(event);
814-
}
815-
}
816-
mFetchedMonths[0] = previousMonth;
802+
mPreviousPeriodEvents = null;
803+
mCurrentPeriodEvents = null;
804+
mNextPeriodEvents = null;
805+
mFetchedPeriod = -1;
817806
}
818807

819-
// Get events of this month.
820-
if (mFetchedMonths[1] < 1 || mFetchedMonths[1] != day.get(Calendar.MONTH)+1 || mRefreshEvents) {
821-
if (!containsValue(lastFetchedMonth, day.get(Calendar.MONTH)+1) && !isInEditMode()) {
822-
List<WeekViewEvent> events = mMonthChangeListener.onMonthChange(day.get(Calendar.YEAR), day.get(Calendar.MONTH) + 1);
823-
sortEvents(events);
824-
for (WeekViewEvent event : events) {
825-
cacheEvent(event);
826-
}
827-
}
828-
mFetchedMonths[1] = day.get(Calendar.MONTH)+1;
829-
}
830-
831-
// Get events of next month.
832-
if (mFetchedMonths[2] < 1 || mFetchedMonths[2] != nextMonth || mRefreshEvents) {
833-
if (!containsValue(lastFetchedMonth, nextMonth) && !isInEditMode()) {
834-
List<WeekViewEvent> events = mMonthChangeListener.onMonthChange(nextMonth == 1 ? day.get(Calendar.YEAR) + 1 : day.get(Calendar.YEAR), nextMonth);
835-
sortEvents(events);
836-
for (WeekViewEvent event : events) {
837-
cacheEvent(event);
808+
if(mWeekViewLoader != null){
809+
int periodToFetch = (int) mWeekViewLoader.toWeekViewPeriodIndex(day);
810+
if (!isInEditMode() && (mFetchedPeriod < 0 || mFetchedPeriod != periodToFetch || mRefreshEvents)) {
811+
List<WeekViewEvent> previousPeriodEvents = null;
812+
List<WeekViewEvent> currentPeriodEvents = null;
813+
List<WeekViewEvent> nextPeriodEvents = null;
814+
815+
if(mPreviousPeriodEvents != null && mCurrentPeriodEvents != null && mNextPeriodEvents != null){
816+
if(periodToFetch == mFetchedPeriod-1){
817+
currentPeriodEvents = mPreviousPeriodEvents;
818+
nextPeriodEvents = mCurrentPeriodEvents;
819+
}else if(periodToFetch == mFetchedPeriod){
820+
previousPeriodEvents = mPreviousPeriodEvents;
821+
currentPeriodEvents = mCurrentPeriodEvents;
822+
nextPeriodEvents = mNextPeriodEvents;
823+
}else if(periodToFetch == mFetchedPeriod+1){
824+
previousPeriodEvents = mCurrentPeriodEvents;
825+
currentPeriodEvents = mNextPeriodEvents;
826+
}
838827
}
828+
if(currentPeriodEvents == null)
829+
currentPeriodEvents = mWeekViewLoader.onLoad(periodToFetch);
830+
if(previousPeriodEvents == null)
831+
previousPeriodEvents = mWeekViewLoader.onLoad(periodToFetch-1);
832+
if(nextPeriodEvents == null)
833+
nextPeriodEvents = mWeekViewLoader.onLoad(periodToFetch+1);
834+
835+
836+
//clear events
837+
mEventRects.clear();
838+
sortAndCacheEvents(previousPeriodEvents);
839+
sortAndCacheEvents(currentPeriodEvents);
840+
sortAndCacheEvents(nextPeriodEvents);
841+
842+
mPreviousPeriodEvents = previousPeriodEvents;
843+
mCurrentPeriodEvents = currentPeriodEvents;
844+
mNextPeriodEvents = nextPeriodEvents;
845+
mFetchedPeriod = periodToFetch;
839846
}
840-
mFetchedMonths[2] = nextMonth;
841847
}
842848

843849
// Prepare to calculate positions of each events.
@@ -886,6 +892,13 @@ private void cacheEvent(WeekViewEvent event) {
886892
mEventRects.add(new EventRect(event, event, null));
887893
}
888894

895+
private void sortAndCacheEvents(List<WeekViewEvent> events){
896+
sortEvents(events);
897+
for(WeekViewEvent event : events){
898+
cacheEvent(event);
899+
}
900+
}
901+
889902
/**
890903
* Sorts the events in ascending order.
891904
* @param events The events to be sorted.
@@ -1014,37 +1027,6 @@ private boolean isTimeAfterOrEquals(Calendar time1, Calendar time2) {
10141027
return !(time1 == null || time2 == null) && time1.getTimeInMillis() >= time2.getTimeInMillis();
10151028
}
10161029

1017-
/**
1018-
* Deletes the events of the months that are too far away from the current month.
1019-
* @param currentDay The current day.
1020-
*/
1021-
private void deleteFarMonths(Calendar currentDay) {
1022-
1023-
if (mEventRects == null) return;
1024-
1025-
Calendar nextMonth = (Calendar) currentDay.clone();
1026-
nextMonth.add(Calendar.MONTH, 1);
1027-
nextMonth.set(Calendar.DAY_OF_MONTH, nextMonth.getActualMaximum(Calendar.DAY_OF_MONTH));
1028-
nextMonth.set(Calendar.HOUR_OF_DAY, 12);
1029-
nextMonth.set(Calendar.MINUTE, 59);
1030-
nextMonth.set(Calendar.SECOND, 59);
1031-
1032-
Calendar prevMonth = (Calendar) currentDay.clone();
1033-
prevMonth.add(Calendar.MONTH, -1);
1034-
prevMonth.set(Calendar.DAY_OF_MONTH, 1);
1035-
prevMonth.set(Calendar.HOUR_OF_DAY, 0);
1036-
prevMonth.set(Calendar.MINUTE, 0);
1037-
prevMonth.set(Calendar.SECOND, 0);
1038-
1039-
List<EventRect> newEvents = new ArrayList<EventRect>();
1040-
for (EventRect eventRect : mEventRects) {
1041-
boolean isFarMonth = eventRect.event.getStartTime().getTimeInMillis() > nextMonth.getTimeInMillis() || eventRect.event.getEndTime().getTimeInMillis() < prevMonth.getTimeInMillis();
1042-
if (!isFarMonth) newEvents.add(eventRect);
1043-
}
1044-
mEventRects.clear();
1045-
mEventRects.addAll(newEvents);
1046-
}
1047-
10481030
@Override
10491031
public void invalidate() {
10501032
super.invalidate();
@@ -1068,11 +1050,21 @@ public EventClickListener getEventClickListener() {
10681050
}
10691051

10701052
public MonthChangeListener getMonthChangeListener() {
1071-
return mMonthChangeListener;
1053+
if(mWeekViewLoader instanceof MonthLoader)
1054+
return ((MonthLoader) mWeekViewLoader).getOnMonthChangeListener();
1055+
return null;
10721056
}
10731057

10741058
public void setMonthChangeListener(MonthChangeListener monthChangeListener) {
1075-
this.mMonthChangeListener = monthChangeListener;
1059+
this.mWeekViewLoader = new MonthLoader(monthChangeListener);
1060+
}
1061+
1062+
public WeekViewLoader getWeekViewLoader(){
1063+
return mWeekViewLoader;
1064+
}
1065+
1066+
public void setWeekViewLoader(WeekViewLoader loader){
1067+
this.mWeekViewLoader = loader;
10761068
}
10771069

10781070
public EventLongPressListener getEventLongPressListener() {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.alamkanak.weekview;
2+
3+
import java.util.Calendar;
4+
import java.util.List;
5+
6+
public interface WeekViewLoader {
7+
/**
8+
* Convert a date into a double that will be used to reference when you're loading data.
9+
*
10+
* All periods that have the same integer part, define one period. Dates that are later in time should have a greater return value.
11+
*
12+
* @param instance the date
13+
* @return The period index in which the date falls (floating point number).
14+
*/
15+
public double toWeekViewPeriodIndex(Calendar instance);
16+
17+
/**
18+
* Load the events within the period
19+
* @param periodIndex the period to load
20+
* @return A list with the events of this period
21+
*/
22+
public List<WeekViewEvent> onLoad(int periodIndex);
23+
}

0 commit comments

Comments
 (0)