Skip to content

Commit b73991c

Browse files
More optimizations, by caching formatted dates and times.
1 parent 09435f8 commit b73991c

File tree

3 files changed

+50
-15
lines changed

3 files changed

+50
-15
lines changed

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

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import android.text.*
1313
import android.text.format.DateFormat
1414
import android.text.style.StyleSpan
1515
import android.util.AttributeSet
16-
import android.util.Log
1716
import android.util.TypedValue
1817
import android.view.*
1918
import android.widget.OverScroller
@@ -973,6 +972,9 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
973972
private val timeChangedBroadcastReceiver: TimeChangedBroadcastReceiver
974973
private var today: Calendar = WeekViewUtil.today()
975974
private val containsAllDayEventCache = HashMap<Pair<SimpleDate, Int>, Boolean>()
975+
private val weekDayTitleFormatterCache = HashMap<SimpleDate, String>()
976+
private val weekDaySubtitleFormatterCache = HashMap<SimpleDate, String>()
977+
private val timeFormatterCache = HashMap<Pair<Int, Int>, String>()
976978

977979
//endregion fields and properties
978980

@@ -1217,7 +1219,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
12171219
mTimeTextWidth = 0f
12181220
for (i in 0 until numberOfPeriods) {
12191221
// Measure time string and get max width.
1220-
val time = dateTimeInterpreter.interpretTime(i, i % 2 * 30)
1222+
val time = getFormattedTime(i, i % 2 * 30)
12211223
mTimeTextWidth = Math.max(mTimeTextWidth, mTimeTextPaint.measureText(time))
12221224
}
12231225
}
@@ -1275,17 +1277,13 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
12751277
val minutes: Int
12761278
val hour: Int
12771279
val timesPerHour = 60.0f / timeColumnResolution
1278-
12791280
timeSpacing = hourHeight / timesPerHour
12801281
hour = mMinTime + i / timesPerHour.toInt()
12811282
minutes = i % timesPerHour.toInt() * (60 / timesPerHour.toInt())
1282-
1283-
12841283
// Calculate the top of the rectangle where the time text will go
12851284
val top = headerHeight + weekDaysHeaderRowTotalPadding + mCurrentOrigin.y + timeSpacing * i + spaceBelowAllDayEvents
1286-
12871285
// Get the time to be displayed, as a String.
1288-
val time = dateTimeInterpreter.interpretTime(hour, minutes)
1286+
val time = getFormattedTime(hour, minutes)
12891287
// Draw the text if its y position is not outside of the visible area. The pivot point of the text is the point at the bottom-right corner.
12901288
if (top < height)
12911289
canvas.drawText(time, mTimeTextWidth + headerColumnPadding, top + mTimeTextHeight, mTimeTextPaint)
@@ -1538,12 +1536,12 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
15381536
continue
15391537
}
15401538
// Draw the day labels title
1541-
val dayLabel = dateTimeInterpreter.interpretDate(day)
1539+
val dayLabel = getFormattedWeekDayTitle(day)
15421540
canvas.drawText(dayLabel, startPixel + mWidthPerDay / 2, headerWeekDayTitleTextHeight + weekDayHeaderRowPaddingTop, if (isToday) mHeaderWeekDayTitleTodayTextPaint else mHeaderWeekDayTitleTextPaint)
15431541

15441542
//draw day subtitle
15451543
if (isSubtitleHeaderEnabled) {
1546-
val subtitleText = weekDaySubtitleInterpreter!!.interpretDate(day)
1544+
val subtitleText = getFormattedWeekDaySubtitle(day)
15471545
canvas.drawText(subtitleText, startPixel + mWidthPerDay / 2, headerTitleAndSubtitleTextHeight + weekDayHeaderRowPaddingTop,
15481546
if (isToday) mHeaderWeekDaySubtitleTodayTextPaint else mHeaderWeekDaySubtitleTextPaint)
15491547
}
@@ -1566,6 +1564,36 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
15661564
}
15671565
}
15681566

1567+
private fun getFormattedTime(hour: Int, minutes: Int): String {
1568+
val cacheKey = Pair(hour, minutes)
1569+
val cachedResult = timeFormatterCache[cacheKey]
1570+
if (cachedResult != null)
1571+
return cachedResult
1572+
val result = dateTimeInterpreter.interpretTime(hour, minutes)
1573+
timeFormatterCache[cacheKey] = result
1574+
return result
1575+
}
1576+
1577+
private fun getFormattedWeekDayTitle(cal: Calendar): String {
1578+
val cacheKey = SimpleDate(cal)
1579+
val cachedResult = weekDayTitleFormatterCache[cacheKey]
1580+
if (cachedResult != null)
1581+
return cachedResult
1582+
val result = dateTimeInterpreter.interpretDate(cal)
1583+
weekDayTitleFormatterCache[cacheKey] = result
1584+
return result
1585+
}
1586+
1587+
private fun getFormattedWeekDaySubtitle(cal: Calendar): String {
1588+
val cacheKey = SimpleDate(cal)
1589+
val cachedResult = weekDaySubtitleFormatterCache[cacheKey]
1590+
if (cachedResult != null)
1591+
return cachedResult
1592+
val result = weekDaySubtitleInterpreter!!.interpretDate(cal)
1593+
weekDaySubtitleFormatterCache[cacheKey] = result
1594+
return result
1595+
}
1596+
15691597
/**
15701598
* Get the time and date where the user clicked on.
15711599
*
@@ -1829,8 +1857,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
18291857
* @param day The day where the user is currently is.
18301858
*/
18311859
private fun getMoreEvents(day: Calendar) {
1832-
containsAllDayEventCache.clear()
1833-
Log.d("AppLog", "getMoreEvents")
1860+
clearOptimizationsCaches()
18341861
// Get more events if the month is changed.
18351862
if (mEventRects == null)
18361863
mEventRects = ArrayList()
@@ -1873,11 +1900,18 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
18731900
}
18741901

18751902
private fun clearEvents() {
1876-
containsAllDayEventCache.clear()
1903+
clearOptimizationsCaches()
18771904
mEventRects!!.clear()
18781905
mEvents.clear()
18791906
}
18801907

1908+
private fun clearOptimizationsCaches() {
1909+
containsAllDayEventCache.clear()
1910+
timeFormatterCache.clear()
1911+
weekDayTitleFormatterCache.clear()
1912+
weekDaySubtitleFormatterCache.clear()
1913+
}
1914+
18811915
/**
18821916
* Cache the event for smooth scrolling functionality.
18831917
*

library/src/main/java/com/alamkanak/weekview/WeekViewUtil.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import java.text.SimpleDateFormat
77
import java.util.*
88

99
object WeekViewUtil {
10-
11-
1210
/////////////////////////////////////////////////////////////////
1311
//
1412
// Helper methods.

sample/src/main/java/com/alamkanak/weekview/sample/WholeViewSnappingActivity.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import kotlinx.android.synthetic.main.activity_base.*
1515
import java.text.SimpleDateFormat
1616
import java.util.*
1717

18+
1819
/**
1920
* Activity to demonstrate snapping of the whole view, for example week-by-week.
2021
*/
@@ -40,7 +41,9 @@ class WholeViewSnappingActivity : BasicActivity() {
4041
weekView.scrollListener = object : WeekView.ScrollListener {
4142
val monthFormatter = SimpleDateFormat("MMM", Locale.getDefault())
4243
override fun onFirstVisibleDayChanged(newFirstVisibleDay: Calendar, oldFirstVisibleDay: Calendar?) {
43-
weekView.sideTitleText = monthFormatter.format(newFirstVisibleDay.time)
44+
//we show just the month here, so no need to update it every time
45+
if (oldFirstVisibleDay == null || oldFirstVisibleDay.get(Calendar.MONTH) != newFirstVisibleDay.get(Calendar.MONTH))
46+
weekView.sideTitleText = monthFormatter.format(newFirstVisibleDay.time)
4447
}
4548
}
4649
draggable_view.visibility = View.GONE

0 commit comments

Comments
 (0)