Skip to content

Commit 7a3d4e1

Browse files
committed
add selected cell indication for series calendar
1 parent 27fe8f9 commit 7a3d4e1

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

features/feature_statistics_detail/src/main/java/com/example/util/simpletimetracker/feature_statistics_detail/customView/SeriesCalendarView.kt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.example.util.simpletimetracker.feature_statistics_detail.customView
22

3+
import android.animation.Animator
4+
import android.animation.ValueAnimator
35
import android.annotation.SuppressLint
46
import android.content.Context
57
import android.graphics.Canvas
@@ -36,6 +38,7 @@ class SeriesCalendarView @JvmOverloads constructor(
3638
// Attrs
3739
private var legendTextSize: Float = 0f
3840
private var legendTextColor: Int = 0
41+
private var selectedCellColor: Int = 0
3942
// Attrs
4043

4144
private val columnsCount: Int = 26
@@ -51,11 +54,18 @@ class SeriesCalendarView @JvmOverloads constructor(
5154
private var chartFullWidth: Float = 0f
5255
private var cellNotPresentColorAlpha = 0.2f
5356
private var cellPresentColorAlphaBase = 0.6f
57+
private var selectedCell: Data? = null
58+
private var selectedCellAlpha: Int = 0
59+
private var selectedCellAnimator: Animator? = null
60+
private val selectedCellWidthRatio: Float = 0.3f
61+
private val selectedCellAnimationDurationMs: Long = 3_000
62+
private val selectedCellStartAlpha: Float = 0.4f
5463
private var listener: (ViewData, Coordinates) -> Unit = { _, _ -> }
5564

5665
private val cellPresentPaint: Paint = Paint()
5766
private val cellNotPresentPaint: Paint = Paint()
5867
private val legendTextPaint: Paint = Paint()
68+
private val selectedCellPaint: Paint = Paint()
5969

6070
private val singleTapDetector = SingleTapDetector(
6171
context = context,
@@ -108,6 +118,7 @@ class SeriesCalendarView @JvmOverloads constructor(
108118

109119
calculateDimensions()
110120
drawCells(canvas, w, h)
121+
drawSelectedCell(canvas)
111122
}
112123

113124
@SuppressLint("ClickableViewAccessibility")
@@ -160,6 +171,8 @@ class SeriesCalendarView @JvmOverloads constructor(
160171
getDimensionPixelSize(R.styleable.SeriesCalendarView_seriesLegendTextSize, 14).toFloat()
161172
legendTextColor =
162173
getColor(R.styleable.SeriesCalendarView_seriesLegendTextColor, Color.BLACK)
174+
selectedCellColor =
175+
getColor(R.styleable.SeriesCalendarView_seriesSelectedCellColor, Color.BLACK)
163176
}
164177
}
165178

@@ -180,10 +193,15 @@ class SeriesCalendarView @JvmOverloads constructor(
180193
color = legendTextColor
181194
textSize = legendTextSize
182195
}
196+
selectedCellPaint.apply {
197+
isAntiAlias = true
198+
style = Paint.Style.FILL
199+
}
183200
}
184201

185202
private fun initEditMode() {
186203
if (isInEditMode) {
204+
setCellColor(Color.RED)
187205
(30 downTo 1).toList()
188206
.map { ViewData.Present(0, "", ViewData.ColorLevel.THREE) }
189207
.let { setData(it, rowsCount) }
@@ -257,6 +275,27 @@ class SeriesCalendarView @JvmOverloads constructor(
257275
}
258276
}
259277

278+
private fun drawSelectedCell(canvas: Canvas) {
279+
val selectedCell = selectedCell ?: return
280+
281+
selectedCellPaint.color = if (selectedCell.cell is ViewData.Present) {
282+
Color.WHITE
283+
} else {
284+
selectedCellColor
285+
}
286+
selectedCellPaint.alpha = selectedCellAlpha
287+
288+
val boxWidth = selectedCell.boxRight - selectedCell.boxLeft
289+
val boxHeight = selectedCell.boxBottom - selectedCell.boxTop
290+
291+
canvas.drawCircle(
292+
selectedCell.boxLeft + boxWidth / 2f,
293+
selectedCell.boxTop + boxHeight / 2f,
294+
boxWidth * selectedCellWidthRatio / 2f,
295+
selectedCellPaint,
296+
)
297+
}
298+
260299
private fun getPresentCellFinalAlpha(colorLevel: ViewData.ColorLevel): Int {
261300
val maxLevel = ViewData.ColorLevel.entries.size
262301
val alphaCoefficient = if (maxLevel > 1) {
@@ -268,12 +307,32 @@ class SeriesCalendarView @JvmOverloads constructor(
268307
return (255 * baseAlpha).toInt()
269308
}
270309

310+
private fun animateSelectedCell() {
311+
val from = 255 * selectedCellStartAlpha
312+
val animator = ValueAnimator.ofInt(from.toInt(), 0)
313+
.also { selectedCellAnimator = it }
314+
315+
animator.duration = selectedCellAnimationDurationMs
316+
animator.addUpdateListener {
317+
selectedCellAlpha = it.animatedValue as? Int
318+
?: return@addUpdateListener
319+
invalidate()
320+
}
321+
animator.start()
322+
}
323+
324+
private fun cancelSelectedCellAnimation() {
325+
selectedCellAnimator?.cancel()
326+
selectedCell = null
327+
}
328+
271329
@Suppress("UNUSED_PARAMETER")
272330
private fun onSwipe(offset: Float, direction: SwipeDetector.Direction, event: MotionEvent) {
273331
if (direction.isHorizontal()) {
274332
parent.requestDisallowInterceptTouchEvent(true)
275333
panFactor = lastPanFactor + offset
276334
coercePan()
335+
cancelSelectedCellAnimation()
277336
invalidate()
278337
}
279338
}
@@ -287,6 +346,7 @@ class SeriesCalendarView @JvmOverloads constructor(
287346
}?.let {
288347
val globalRect = Rect()
289348
getGlobalVisibleRect(globalRect)
349+
selectedCell = it
290350
listener(
291351
it.cell,
292352
// Calculate from the bottom, because when view is half scrolled on the top,
@@ -299,6 +359,7 @@ class SeriesCalendarView @JvmOverloads constructor(
299359
bottom = globalRect.bottom - height + it.boxBottom.toInt(),
300360
),
301361
)
362+
animateSelectedCell()
302363
}
303364
}
304365

features/feature_statistics_detail/src/main/res/layout/statistics_detail_series_calendar_item.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
android:layout_marginEnd="8dp"
1010
app:layout_constraintTop_toTopOf="parent"
1111
app:seriesLegendTextColor="@color/textSecondary"
12-
app:seriesLegendTextSize="14sp" />
12+
app:seriesLegendTextSize="14sp"
13+
app:seriesSelectedCellColor="?appContrastColor" />

features/feature_statistics_detail/src/main/res/values/attrs.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
<declare-styleable name="SeriesCalendarView">
2525
<attr name="seriesLegendTextSize" />
2626
<attr name="seriesLegendTextColor" />
27+
<attr name="seriesSelectedCellColor" format="color" />
2728
</declare-styleable>
2829
</resources>

0 commit comments

Comments
 (0)