效果长这个样子:
代码长下面这个样子:
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.viewpager.widget.ViewPager
/**
* viewpager的圆点指示器
*/
class OvalIndicator @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null
) : View(context, attributeSet) {
private var radius = DEF_RADIUS
private var selectColor: Int = DEF_SELECT_COLOR
private var unSelectColor: Int = DEF_UNSELECT_COLOR
private var ovalInterval = DEF_RADIUS //圆点间的间隔
private var count = 0
private var pageIndex = 0
private val selectPaint = Paint()
private val unSelectPaint = Paint()
init {
val a = context.obtainStyledAttributes(attributeSet, R.styleable.OvalIndicator)
radius = a.getDimension(R.styleable.OvalIndicator_oi_radius, DEF_RADIUS)
ovalInterval = a.getDimension(R.styleable.OvalIndicator_oi_oval_interval, DEF_RADIUS)
selectColor = a.getColor(R.styleable.OvalIndicator_oi_select_color, DEF_SELECT_COLOR)
unSelectColor = a.getColor(R.styleable.OvalIndicator_oi_unselect_color, DEF_UNSELECT_COLOR)
a.recycle()
selectPaint.color = selectColor
unSelectPaint.color = unSelectColor
}
fun setupWithViewPager(viewPager: ViewPager) {
count = viewPager.adapter?.count ?: 0
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageSelected(position: Int) {
pageIndex = position
invalidate()
}
})
invalidate()
}
override fun onDraw(canvas: Canvas?) {
canvas ?: return
if (count < 1) return
val diameter = 2 * radius
val half = (width - diameter * (count) - ovalInterval * (count - 1)) / 2f
for (i in 0 until count) {
val left = half + (diameter + ovalInterval) * i
val top = height / 2f - radius
val bottom = height / 2f + radius
val right = left + diameter
canvas.drawOval(left, top, right, bottom, if (i == pageIndex) selectPaint else unSelectPaint)
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), (2 * radius).toInt())
}
companion object {
private const val DEF_RADIUS = 8f
private const val DEF_SELECT_COLOR = Color.RED
private const val DEF_UNSELECT_COLOR = Color.WHITE
}
}
属性部分长这样:
<declare-styleable name="OvalIndicator">
<!-- 原点半径-->
<attr name="oi_radius" format="dimension" />
<!-- 两个圆点之间的间隔-->
<attr name="oi_oval_interval" format="dimension" />
<!-- 选中的颜色-->
<attr name="oi_select_color" format="color|reference" />
<!-- 未选中的颜色-->
<attr name="oi_unselect_color" format="color|reference" />
</declare-styleable>
用法如下:
xml中:
<cn.zhengshang.uitestbasic.OvalIndicator
android:id="@+id/indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toTopOf="@id/interesting"
app:oi_radius="10dp"
app:oi_unselect_color="@android:color/holo_green_dark" />
代码中:
indicator = findViewById(R.id.indicator)
indicator.setupWithViewPager(pager)