概述
首先了解下, 自定义View的三部曲.
1:onMeasure方法
此方法主要目的, 就是根据xml的
android:layout_width="wrap_content"
android:layout_height="wrap_content"
wrap_content
match_parent
这2个属性, 来确定测量自身的大小.
当然, 这2个值, 只是parent
告诉你, 需要按照此规则来测量, 如果你是一个坏孩子, 那么可以无视测量规则, 任意设置一个宽度和高度, 比如: setMeasuredDimension(1万, 2万)
就是如此简单;
2:onLayout方法
如果你是自定义View, 此方法可以不必override
如果你是自定义的ViewGroup, 那么就必须override
, 此方法的目的就是由你决定child view在界面上的位置.
3:onDraw方法
在这个方法里面, 你可以展开你天才般的做图功能, 想画啥就画啥. 美美的view, 就这样出来了.
友情提示:如果你是自定义的ViewGroup, 还需要调用setWillNotDraw(false)
方法, 否则onDraw
方法不会执行哦
不着急, 分析一波:
1: 有2个可以滑动的浮子
2: 需要一个轨道, 浮子在轨道上滑动
3: 浮子之间的颜色不一样
4: 浮子上面有进度文本
步骤不多, 还是很简单就能实现的.
因为都是一个draw操作, 所以这里就直接贴上onDraw的代码了:
onDraw
override fun onDraw(canvas: Canvas) {
//canvas.drawColor(Color.parseColor("#80000000"))
paint.style = Paint.Style.FILL
paint.color = trackColor
paint.textSize = textSize
//绘制轨道
trackRectF.set((paddingLeft + thumbRadius).toFloat(), trackTop,
measuredWidth.toFloat() - paddingRight - thumbRadius, trackTop + trackHeight)
canvas.drawRoundRect(trackRectF, trackRoundRadius.toFloat(), trackRoundRadius.toFloat(), paint)
//计算浮子矩形坐标位置
calcThumbValueRect()
//绘制进度
paint.style = Paint.Style.FILL
paint.color = progressColor
progressRectF.set(minValueRectF.centerX(), trackRectF.top, maxValueRectF.centerX(), trackRectF.bottom)
canvas.drawRoundRect(progressRectF, trackRoundRadius.toFloat(), trackRoundRadius.toFloat(), paint)
//绘制浮子
drawThumb(canvas, minValueRectF)
drawThumb(canvas, maxValueRectF)
//绘制提示文本
drawText(canvas, minValueRectF, currentMinValue)
drawText(canvas, maxValueRectF, currentMaxValue)
}
private fun drawThumb(canvas: Canvas, rectF: RectF) {
paint.style = Paint.Style.FILL
paint.color = thumbColor
canvas.drawCircle(rectF.centerX(), rectF.centerY(), thumbRadius.toFloat(), paint)
//绘制浮子外圈
paint.style = Paint.Style.STROKE
paint.strokeWidth = 2 * density
paint.color = thumbOutLineColor
canvas.drawCircle(rectF.centerX(), rectF.centerY(), thumbRadius.toFloat() - 1 * density, paint)
}
private fun drawText(canvas: Canvas, rectF: RectF, progress: Int) {
paint.style = Paint.Style.FILL_AND_STROKE
paint.color = textColor
paint.strokeWidth = 1f
val text: String = rangeListener?.getProgressText(progress) ?: "$progress%"
canvas.drawText(text,
Math.min(Math.max(0f, rectF.centerX() - textWidth(paint, text) / 2),
viewWidth - textWidth(paint, text)),
paddingTop + textHeight(paint) - paint.descent(),
paint)
}
private fun calcThumbValueRect() {
val x = (viewWidth - 2 * thumbRadius) * (currentMinValue.toFloat() / 100f) + paddingLeft
minValueRectF.set(
x,
trackTop + trackHeight / 2 - thumbRadius,
x + 2 * thumbRadius,
trackTop + trackHeight / 2 + thumbRadius
)
val x2 = (viewWidth - 2 * thumbRadius) * (currentMaxValue.toFloat() / 100f) + paddingLeft
maxValueRectF.set(
x2,
trackTop + trackHeight / 2 - thumbRadius,
x2 + 2 * thumbRadius,
trackTop + trackHeight / 2 + thumbRadius
)
}
手势处理:
/**手势按在那个点上, 不分最大点和最小点*/
private var touchValue: Int = -1
private var notTouchValue: Int = -1
override fun onTouchEvent(event: MotionEvent): Boolean {
val action = MotionEventCompat.getActionMasked(event)
when (action) {
MotionEvent.ACTION_DOWN -> {
if (minValueRectF.contains(event.x, event.y)) {
touchValue = currentMinValue
notTouchValue = currentMaxValue
} else if (maxValueRectF.contains(event.x, event.y)) {
touchValue = currentMaxValue
notTouchValue = currentMinValue
} else {
touchValue = -1
notTouchValue = -1
}
}
MotionEvent.ACTION_MOVE -> {
if (touchValue >= 0) {
parent.requestDisallowInterceptTouchEvent(true)
//按在了点上
touchValue = ((event.x - paddingLeft - thumbRadius) / (viewWidth - 2 * thumbRadius) * 100).toInt()
touchValue = ensureValue(touchValue)
//L.e("call: onTouchEvent ->$viewWidth ${event.x} $touchValue")
if (Math.abs(touchValue - notTouchValue) >= MIN_RANGE) {
currentMinValue = Math.min(touchValue, notTouchValue)
currentMaxValue = Math.max(touchValue, notTouchValue)
postInvalidate()
rangeListener?.onRangeChange(currentMinValue, currentMaxValue)
}
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
parent.requestDisallowInterceptTouchEvent(false)
}
}
return true
}
联系作者
请使用QQ扫码加群, 小伙伴们在等着你哦!
关注我的公众号, 每天都能一起玩耍哦!
最后
以上就是傻傻服饰为你收集整理的Kotlin-->范围选择进度条, 双向SeekBar的全部内容,希望文章能够帮你解决Kotlin-->范围选择进度条, 双向SeekBar所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复