Skip to content

Instantly share code, notes, and snippets.

@bagus2x
Created March 25, 2022 01:14
Show Gist options
  • Save bagus2x/cc7b9e5da3584e084ab2b295cf34a291 to your computer and use it in GitHub Desktop.
Save bagus2x/cc7b9e5da3584e084ab2b295cf34a291 to your computer and use it in GitHub Desktop.
Simple custom view for viewpager indicator
package com.bagus2x.indicator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
class Indicator : View {
private lateinit var paintCircle: Paint
private lateinit var paintSelectedCircle: Paint
private val Int.dp get() = (this * resources.displayMetrics.density).toInt()
var spaceBy: Int = 4.dp
var circleRadius: Int = 8.dp
var circleColor: Int = Color.GRAY
var selectedCircleColor: Int = Color.BLACK
var currentPage: Int = 0
set(value) {
field = value
invalidate()
}
var totalPage: Int = 0
set(value) {
field = value
invalidate()
}
constructor(context: Context) : super(context) {
initialize(context, null)
}
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
initialize(context, attributeSet)
}
private fun initialize(context: Context, attributeSet: AttributeSet?) {
attributeSet?.let { attrs ->
context.obtainStyledAttributes(attrs, R.styleable.Indicator).apply {
spaceBy = getDimensionPixelSize(R.styleable.Indicator_spaceBy, spaceBy)
circleRadius = getDimensionPixelSize(
R.styleable.Indicator_circleRadius,
circleRadius
)
circleColor = getColor(R.styleable.Indicator_circleColor, circleColor)
selectedCircleColor = getColor(
R.styleable.Indicator_selectedCircleColor,
selectedCircleColor
)
currentPage = getInt(R.styleable.Indicator_currentPage, currentPage)
totalPage = getInt(R.styleable.Indicator_totalPage, totalPage)
recycle()
}
}
paintCircle = Paint().apply {
color = circleColor
style = Paint.Style.FILL
}
paintSelectedCircle = Paint().apply {
color = selectedCircleColor
style = Paint.Style.FILL
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val measuredWidth = measureWidth(widthMeasureSpec)
val measuredHeight = measureHeight(heightMeasureSpec)
setMeasuredDimension(measuredWidth, measuredHeight)
}
private fun measureWidth(widthMeasureSpec: Int): Int {
return when (MeasureSpec.getMode(widthMeasureSpec)) {
MeasureSpec.EXACTLY -> MeasureSpec.getSize(widthMeasureSpec)
else -> totalPage * (circleRadius * 2) + (spaceBy * (totalPage - 1)) + paddingStart + paddingEnd
}
}
private fun measureHeight(heightMeasureSpec: Int): Int {
return when (MeasureSpec.getMode(heightMeasureSpec)) {
MeasureSpec.EXACTLY -> MeasureSpec.getSize(heightMeasureSpec)
else -> circleRadius * 2 + paddingTop + paddingBottom
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
var currentXCenter = (paddingStart + circleRadius).toFloat()
val currentYCenter = (paddingTop + circleRadius).toFloat()
repeat(totalPage) { page ->
val paint = if (page == currentPage) paintSelectedCircle else paintCircle
canvas.drawCircle(currentXCenter, currentYCenter, circleRadius.toFloat(), paint)
currentXCenter += spaceBy + (2 * circleRadius)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment