Skip to content

Commit ef2a323

Browse files
committed
Make minor code improvements
1 parent 11f849e commit ef2a323

File tree

9 files changed

+92
-153
lines changed

9 files changed

+92
-153
lines changed

core/src/main/java/com/alamkanak/weekview/CalendarRenderer.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,7 @@ private class BackgroundGridDrawer(
169169
}
170170

171171
private fun createHourLines(): FloatArray {
172-
val headerHeight = viewState.getTotalHeaderHeight()
173-
val gridHeight = viewState.viewHeight - headerHeight.toInt()
172+
val gridHeight = viewState.viewHeight - viewState.headerHeight
174173
val linesPerDay = (gridHeight / viewState.hourHeight) + 1
175174
val overallLines = linesPerDay.roundToInt() * (viewState.numberOfVisibleDays + 1)
176175
return FloatArray(overallLines * 4) // 4 lines make a cube in the grid

core/src/main/java/com/alamkanak/weekview/EventChipBoundsCalculator.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ internal class EventChipBoundsCalculator(
5050
eventChip: EventChip,
5151
startPixel: Float
5252
): RectF {
53-
val top = viewState.headerTextHeight + viewState.headerRowPadding * 1.5f
53+
val padding = viewState.headerRowPadding
54+
55+
val top = padding + viewState.dateLabelHeight + padding / 2
5456
val height = viewState.allDayEventTextPaint.textSize + viewState.eventPaddingVertical * 2
5557
val bottom = top + height
5658

core/src/main/java/com/alamkanak/weekview/HeaderRenderer.kt

Lines changed: 43 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import android.text.StaticLayout
77
import android.util.SparseArray
88
import androidx.collection.ArrayMap
99
import java.util.Calendar
10+
import kotlin.math.max
1011
import kotlin.math.roundToInt
1112

1213
internal class HeaderRenderer(
@@ -19,8 +20,7 @@ internal class HeaderRenderer(
1920

2021
private val headerRowUpdater = HeaderRowUpdater(
2122
viewState = viewState,
22-
labelLayouts = dateLabelLayouts,
23-
eventChipsCache = eventChipsCache
23+
labelLayouts = dateLabelLayouts
2424
)
2525

2626
private val dateLabelDrawer = DayLabelsDrawer(
@@ -50,69 +50,39 @@ internal class HeaderRenderer(
5050
}
5151

5252
override fun render(canvas: Canvas) {
53-
if (headerRowUpdater.isRequired()) {
54-
headerRowUpdater.update()
55-
}
56-
dateLabelDrawer.draw(canvas)
57-
5853
if (eventsUpdater.isRequired()) {
5954
eventsUpdater.update()
6055
}
6156
eventsDrawer.draw(canvas)
57+
58+
headerRowUpdater.update()
59+
dateLabelDrawer.draw(canvas)
6260
}
6361
}
6462

6563
private class HeaderRowUpdater(
6664
private val viewState: ViewState,
67-
private val labelLayouts: SparseArray<StaticLayout>,
68-
private val eventChipsCache: EventChipsCache
65+
private val labelLayouts: SparseArray<StaticLayout>
6966
) : Updater {
7067

71-
private var previousHorizontalOrigin: Float? = null
72-
private val previousAllDayEventIds = mutableSetOf<Long>()
73-
74-
override fun isRequired(): Boolean {
75-
val didScrollHorizontally = previousHorizontalOrigin != viewState.currentOrigin.x
76-
val currentTimeColumnWidth = viewState.timeTextWidth + viewState.timeColumnPadding * 2
77-
val didTimeColumnChange = currentTimeColumnWidth != viewState.timeColumnWidth
78-
val allDayEvents = eventChipsCache.allDayEventChipsInDateRange(viewState.dateRange)
79-
.map { it.eventId }
80-
.toSet()
81-
val didEventsChange = allDayEvents.hashCode() != previousAllDayEventIds.hashCode()
82-
return (didScrollHorizontally || didTimeColumnChange || didEventsChange).also {
83-
previousAllDayEventIds.clear()
84-
previousAllDayEventIds += allDayEvents
68+
override fun update() {
69+
val missingDates = viewState.dateRange.filterNot { labelLayouts.contains(it.toEpochDays()) }
70+
for (date in missingDates) {
71+
val key = date.toEpochDays()
72+
labelLayouts.put(key, calculateStaticLayoutForDate(date))
8573
}
86-
}
8774

88-
override fun update() {
89-
val dateLabels = updateDateLabels(viewState)
90-
updateHeaderHeight(viewState, dateLabels)
75+
val dateLabels = viewState.dateRange.map { labelLayouts[it.toEpochDays()] }
76+
updateHeaderHeight(dateLabels)
9177
}
9278

93-
private fun updateDateLabels(state: ViewState): List<StaticLayout> {
94-
val textLayouts = state.dateRange.map { date ->
95-
date.toEpochDays() to calculateStaticLayoutForDate(date)
96-
}.toMap()
97-
98-
labelLayouts.clear()
99-
labelLayouts += textLayouts
100-
101-
return textLayouts.values.toList()
102-
}
79+
private fun <E> SparseArray<E>.contains(key: Int): Boolean = indexOfKey(key) >= 0
10380

10481
private fun updateHeaderHeight(
105-
state: ViewState,
10682
dateLabels: List<StaticLayout>
10783
) {
10884
val maximumLayoutHeight = dateLabels.map { it.height.toFloat() }.max() ?: 0f
109-
state.headerTextHeight = maximumLayoutHeight
110-
refreshHeaderHeight()
111-
}
112-
113-
private fun refreshHeaderHeight() {
114-
val visibleEvents = eventChipsCache.allDayEventChipsInDateRange(viewState.dateRange)
115-
viewState.hasEventInHeader = visibleEvents.isNotEmpty()
85+
viewState.dateLabelHeight = maximumLayoutHeight
11686
viewState.refreshHeaderHeight()
11787
}
11888

@@ -135,23 +105,23 @@ private class DayLabelsDrawer(
135105
) : Drawer {
136106

137107
override fun draw(canvas: Canvas) {
138-
val left = viewState.timeColumnWidth
139-
val top = 0f
140-
val right = canvas.width.toFloat()
141-
val bottom = viewState.getTotalHeaderHeight()
142-
143-
canvas.drawInBounds(left, top, right, bottom) {
108+
canvas.drawInBounds(
109+
left = viewState.timeColumnWidth,
110+
top = 0f,
111+
right = canvas.width.toFloat(),
112+
bottom = viewState.headerHeight
113+
) {
144114
viewState.dateRangeWithStartPixels.forEach { (date, startPixel) ->
145-
drawLabel(date, startPixel, this)
115+
drawLabel(date, startPixel)
146116
}
147117
}
148118
}
149119

150-
private fun drawLabel(day: Calendar, startPixel: Float, canvas: Canvas) {
120+
private fun Canvas.drawLabel(day: Calendar, startPixel: Float) {
151121
val key = day.toEpochDays()
152122
val textLayout = dateLabelLayouts[key]
153123

154-
canvas.withTranslation(
124+
withTranslation(
155125
x = startPixel + viewState.widthPerDay / 2,
156126
y = viewState.headerRowPadding.toFloat()
157127
) {
@@ -192,7 +162,10 @@ private class AllDayEventsUpdater(
192162

193163
val eventChips = eventChipsCache.allDayEventChipsByDate(date)
194164
for (eventChip in eventChips) {
195-
calculateTextLayout(eventChip, modifiedStartPixel)
165+
val bounds = eventChip.calculateBounds(modifiedStartPixel)
166+
if (bounds != null) {
167+
eventsLabelLayouts[eventChip] = eventChip.calculateTextLayout()
168+
}
196169
}
197170
}
198171

@@ -201,27 +174,18 @@ private class AllDayEventsUpdater(
201174
.map { it.height().roundToInt() }
202175
.max() ?: 0
203176

204-
viewState.updateAllDayEventHeight(maximumChipHeight)
177+
viewState.currentAllDayEventHeight = maximumChipHeight
205178
}
206179

207-
private fun calculateTextLayout(
208-
eventChip: EventChip,
209-
startPixel: Float
210-
) {
211-
val chipRect = boundsCalculator.calculateAllDayEvent(eventChip, startPixel)
212-
eventChip.bounds = if (chipRect.isValidEventBounds) chipRect else null
213-
214-
if (chipRect.isValidEventBounds) {
215-
val textLayout = calculateChipTextLayout(eventChip)
216-
if (textLayout != null) {
217-
eventsLabelLayouts[eventChip] = textLayout
218-
}
219-
}
180+
private fun EventChip.calculateBounds(startPixel: Float): RectF? {
181+
val chipRect = boundsCalculator.calculateAllDayEvent(this, startPixel)
182+
bounds = chipRect
183+
return chipRect.takeIf { it.isValidEventBounds }
220184
}
221185

222-
private fun calculateChipTextLayout(eventChip: EventChip): StaticLayout? {
223-
val event = eventChip.event
224-
val bounds = checkNotNull(eventChip.bounds)
186+
private fun EventChip.calculateTextLayout(): StaticLayout? {
187+
val event = event
188+
val bounds = checkNotNull(bounds)
225189

226190
val fullHorizontalPadding = viewState.eventPaddingHorizontal * 2
227191
val fullVerticalPadding = viewState.eventPaddingVertical * 2
@@ -262,7 +226,7 @@ private class AllDayEventsUpdater(
262226
val chipHeight = lineHeight + fullVerticalPadding
263227
bounds.bottom = bounds.top + chipHeight
264228

265-
return eventChip.ellipsizeText(text, availableWidth, existingTextLayout = textLayout)
229+
return ellipsizeText(text, availableWidth, existingTextLayout = textLayout)
266230
}
267231

268232
/**
@@ -314,12 +278,12 @@ internal class AllDayEventsDrawer(
314278
private val eventChipDrawer = EventChipDrawer(viewState)
315279

316280
override fun draw(canvas: Canvas) {
317-
val left = viewState.timeColumnWidth
318-
val top = 0f
319-
val right = canvas.width.toFloat()
320-
val bottom = viewState.getTotalHeaderHeight()
321-
322-
canvas.drawInBounds(left, top, right, bottom) {
281+
canvas.drawInBounds(
282+
left = viewState.timeColumnWidth,
283+
top = 0f,
284+
right = canvas.width.toFloat(),
285+
bottom = viewState.headerHeight
286+
) {
323287
for ((eventChip, textLayout) in allDayEventLayouts) {
324288
eventChipDrawer.draw(eventChip, canvas, textLayout)
325289
}

core/src/main/java/com/alamkanak/weekview/Renderers.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.alamkanak.weekview
33
import android.graphics.Canvas
44

55
internal interface Updater {
6-
fun isRequired(): Boolean
6+
fun isRequired(): Boolean = true
77
fun update()
88
}
99

core/src/main/java/com/alamkanak/weekview/TimeColumnRenderer.kt

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,15 @@ internal class TimeColumnRenderer(
1111
private val timeLabelLayouts = SparseArray<StaticLayout>()
1212

1313
init {
14-
cacheTimeLabels()
14+
updateTimeLabels()
1515
}
1616

1717
override fun onSizeChanged(width: Int, height: Int) {
18-
timeLabelLayouts.clear()
19-
cacheTimeLabels()
18+
updateTimeLabels()
2019
}
2120

2221
override fun onTimeFormatterChanged(formatter: TimeFormatter) {
23-
timeLabelLayouts.clear()
24-
cacheTimeLabels()
22+
updateTimeLabels()
2523
}
2624

2725
override fun render(canvas: Canvas) = with(viewState) {
@@ -41,16 +39,18 @@ internal class TimeColumnRenderer(
4139
continue
4240
}
4341

44-
val x = timeTextWidth + timeColumnPadding
4542
var y = topMargin - timeTextHeight / 2
4643

4744
// If the hour separator is shown in the time column, move the time label below it
4845
if (showTimeColumnHourSeparator) {
4946
y += timeTextHeight / 2 + hourSeparatorPaint.strokeWidth + timeColumnPadding
5047
}
5148

49+
val label = timeLabelLayouts[hour]
50+
val x = timeColumnWidth - timeColumnPadding
51+
5252
canvas.withTranslation(x, y) {
53-
timeLabelLayouts[hour].draw(this)
53+
label.draw(this)
5454
}
5555

5656
if (showTimeColumnHourSeparator && hour > 0) {
@@ -74,10 +74,21 @@ internal class TimeColumnRenderer(
7474
}
7575
}
7676

77-
private fun cacheTimeLabels() = with(viewState) {
77+
private fun updateTimeLabels() = with(viewState) {
78+
var maxLineLength = 0f
79+
var maxLineHeight = 0
80+
81+
timeLabelLayouts.clear()
7882
for (hour in displayedHours) {
7983
val textLayout = timeFormatter(hour).toTextLayout(timeTextPaint, width = Int.MAX_VALUE)
84+
maxLineLength = textLayout.maxLineLength
85+
maxLineHeight = textLayout.height
8086
timeLabelLayouts.put(hour, textLayout)
8187
}
88+
89+
updateTimeColumnBounds(
90+
lineLength = maxLineLength,
91+
lineHeight = maxLineHeight.toFloat()
92+
)
8293
}
8394
}

0 commit comments

Comments
 (0)