@@ -17,6 +17,7 @@ import android.util.AttributeSet
1717import android.util.TypedValue
1818import android.view.*
1919import android.widget.OverScroller
20+ import com.alamkanak.weekview.MonthLoader.MonthChangeListener
2021import com.alamkanak.weekview.WeekViewUtil.daysBetween
2122import com.alamkanak.weekview.WeekViewUtil.getPassedMinutesInDay
2223import com.alamkanak.weekview.WeekViewUtil.isSameDay
@@ -224,7 +225,11 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
224225 * are loaded in week view. For a MonthLoader events are loaded for every month. You can define
225226 * your custom event loader by extending WeekViewLoader.
226227 */
227- var weekViewLoader: WeekViewLoader ? = null
228+ val weekViewLoader: WeekViewLoader = PrefetchingWeekViewLoader (MonthLoader (object : MonthChangeListener {
229+ override fun onMonthChange (newYear : Int , newMonth : Int ): MutableList <WeekViewEvent >? {
230+ return monthChangeListener?.onMonthChange(newYear, newMonth)
231+ }
232+ }))
228233 var emptyViewClickListener: EmptyViewClickListener ? = null
229234 var emptyViewLongPressListener: EmptyViewLongPressListener ? = null
230235 var scrollListener: ScrollListener ? = null
@@ -359,7 +364,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
359364 // If the tap was on an event then trigger the callback.
360365 if (mEventRects != null && eventClickListener != null ) {
361366 val reversedEventRects = mEventRects
362- Collections .reverse( reversedEventRects!! )
367+ reversedEventRects!! .reverse( )
363368 for (eventRect in reversedEventRects) {
364369 if (newEventIdentifier != eventRect.event.identifier && eventRect.rectF != null && e.x > eventRect.rectF!! .left && e.x < eventRect.rectF!! .right && e.y > eventRect.rectF!! .top && e.y < eventRect.rectF!! .bottom) {
365370 eventClickListener!! .onEventClick(eventRect.originalEvent, eventRect.rectF!! )
@@ -455,7 +460,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
455460
456461 if (eventLongPressListener != null && mEventRects != null ) {
457462 val reversedEventRects = mEventRects
458- Collections .reverse( reversedEventRects!! )
463+ reversedEventRects!! .reverse( )
459464 for (event in reversedEventRects) {
460465 if (event.rectF != null && e.x > event.rectF!! .left && e.x < event.rectF!! .right && e.y > event.rectF!! .top && e.y < event.rectF!! .bottom) {
461466 eventLongPressListener!! .onEventLongPress(event.originalEvent, event.rectF!! )
@@ -491,16 +496,16 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
491496
492497 private val xMinLimit: Float
493498 get() {
494- if (maxDate == null ) {
495- return Integer .MIN_VALUE .toFloat()
499+ return if (maxDate == null ) {
500+ Integer .MIN_VALUE .toFloat()
496501 } else {
497502 val date = maxDate!! .clone() as Calendar
498503 date.add(Calendar .DATE , 1 - realNumberOfVisibleDays)
499504 while (date.before(minDate)) {
500505 date.add(Calendar .DATE , 1 )
501506 }
502507
503- return getXOriginForDate(date)
508+ getXOriginForDate(date)
504509 }
505510 }
506511
@@ -525,11 +530,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
525530 get() = mCurrentOrigin.x + (mWidthPerDay + columnGap) * leftDaysWithGaps +
526531 mHeaderColumnWidth
527532
528- var monthChangeListener: MonthLoader .MonthChangeListener ?
529- get() = if (weekViewLoader is MonthLoader ) (weekViewLoader as MonthLoader ).onMonthChangeListener else null
530- set(value) {
531- this .weekViewLoader = MonthLoader (value)
532- }
533+ var monthChangeListener: MonthChangeListener ? = null
533534
534535 /* *
535536 * the interpreter which provides the text to show in the header column and the header row.
@@ -1404,11 +1405,35 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
14041405 continue
14051406 }
14061407
1407- // Get more events if necessary. We want to store the events 3 months beforehand. Get
1408- // events only when it is the first iteration of the loop.
1409- if (mEventRects == null || mRefreshEvents ||
1410- dayNumber == leftDaysWithGaps + 1 && mFetchedPeriod != weekViewLoader!! .toWeekViewPeriodIndex(day).toInt() &&
1411- Math .abs(mFetchedPeriod - weekViewLoader!! .toWeekViewPeriodIndex(day)) > 0.5 ) {
1408+ // Get more events if necessary.
1409+
1410+ // mFetchedPeriod: currently fetched period index
1411+ // mWeekViewLoader.toWeekViewPeriodIndex(day): index for the day we want to display
1412+ // fetchIndex = 1.0: end of period in the future reached
1413+ // fetchIndex = 0.0: end of period in the past reached
1414+ val fetchIndex = this .weekViewLoader.toWeekViewPeriodIndex(day) - mFetchedPeriod
1415+
1416+ // if we are using the PrefetchingWeekViewLoader class, we need to adjust the bounds
1417+ // so that we wait to fetch new data until we really need it
1418+ var upperBound = 1.0
1419+ var lowerBound = 0.0
1420+
1421+ if (this .weekViewLoader is PrefetchingWeekViewLoader ) {
1422+ // the offset causes the onMonthChangeListener to be trigger when half of the
1423+ // last fetched period is passed
1424+
1425+ // example:
1426+ // if the prefetching period = 1, we load the current period, the next and the previous
1427+ // when half of the next/previous period is passed, the listener is triggered to fetch new data
1428+ val boundOffset = this .weekViewLoader.prefetchingPeriod - 0.5
1429+
1430+ upperBound = 1.0 + boundOffset
1431+ lowerBound = 0.0 - boundOffset
1432+ }
1433+
1434+ if ((mEventRects == null || mRefreshEvents ||
1435+ dayNumber == leftDaysWithGaps + 1 && mFetchedPeriod != this .weekViewLoader.toWeekViewPeriodIndex(day).toInt() &&
1436+ (fetchIndex >= upperBound || fetchIndex <= lowerBound))) {
14121437 getMoreEvents(day)
14131438 mRefreshEvents = false
14141439 }
@@ -1824,7 +1849,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
18241849 if (mEvents == null )
18251850 mEvents = ArrayList ()
18261851
1827- if (weekViewLoader == null && ! isInEditMode)
1852+ if (this . weekViewLoader == null && ! isInEditMode)
18281853 throw IllegalStateException (" You must provide a MonthChangeListener" )
18291854
18301855 // If a refresh was requested then reset some variables.
@@ -1833,18 +1858,16 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
18331858 mFetchedPeriod = - 1
18341859 }
18351860
1836- if (weekViewLoader != null ) {
1837- val periodToFetch = weekViewLoader!! .toWeekViewPeriodIndex(day).toInt()
1838- if (! isInEditMode && (mFetchedPeriod < 0 || mFetchedPeriod != periodToFetch || mRefreshEvents)) {
1839- val newEvents = weekViewLoader!! .onLoad(periodToFetch)
1861+ val periodToFetch = this .weekViewLoader.toWeekViewPeriodIndex(day).toInt()
1862+ if (! isInEditMode && (mFetchedPeriod < 0 || mFetchedPeriod != periodToFetch || mRefreshEvents)) {
1863+ val newEvents = this .weekViewLoader.onLoad(periodToFetch)
18401864
1841- // Clear events.
1842- this .clearEvents()
1843- cacheAndSortEvents(newEvents)
1844- calculateHeaderHeight()
1865+ // Clear events.
1866+ this .clearEvents()
1867+ cacheAndSortEvents(newEvents)
1868+ calculateHeaderHeight()
18451869
1846- mFetchedPeriod = periodToFetch
1847- }
1870+ mFetchedPeriod = periodToFetch
18481871 }
18491872
18501873 // Prepare to calculate positions of each events.
@@ -2427,12 +2450,12 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
24272450 goToNearestOrigin()
24282451
24292452 // Calculate focused point for scale action
2430- if (isZoomFocusPointEnabled) {
2453+ mFocusedPointY = if (isZoomFocusPointEnabled) {
24312454 // Use fractional focus, percentage of height
2432- mFocusedPointY = (height.toFloat() - mHeaderHeight - (weekDaysHeaderRowPadding * 2 ).toFloat() - spaceBelowAllDayEvents) * zoomFocusPoint
2455+ (height.toFloat() - mHeaderHeight - (weekDaysHeaderRowPadding * 2 ).toFloat() - spaceBelowAllDayEvents) * zoomFocusPoint
24332456 } else {
24342457 // Grab focus
2435- mFocusedPointY = detector.focusY
2458+ detector.focusY
24362459 }
24372460
24382461 return true
0 commit comments