Kotlin-->范围选择进度条, 双向SeekBar
范围选择进度条, 双向SeekBar_第1张图片" title="" width="521" height="172" style="border:1px solid black;">
首先了解下, 自定义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扫码加群, 小伙伴们在等着你哦!
关注我的公众号, 每天都能一起玩耍哦!
更多相关文章
- Android(安卓)Thread子线程和主线程的UI交互
- Android6.0来电流程
- android判断快捷方式是否已经创建的方法
- android 中ActivityUI装态保存
- android2.1之后appwidget的一些问题
- ContentProvider 学习之01
- android ImageView.getDrawingCache return NULL一点...
- Android之OpenGL里FBO理解测试实例
- 用cmd 命令更改Android(安卓)的默认虚拟机的地址的方法