范围选择进度条, 双向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扫码加群, 小伙伴们在等着你哦!

关注我的公众号, 每天都能一起玩耍哦!

更多相关文章

  1. Android(安卓)Thread子线程和主线程的UI交互
  2. Android6.0来电流程
  3. android判断快捷方式是否已经创建的方法
  4. android 中ActivityUI装态保存
  5. android2.1之后appwidget的一些问题
  6. ContentProvider 学习之01
  7. android ImageView.getDrawingCache return NULL一点...
  8. Android之OpenGL里FBO理解测试实例
  9. 用cmd 命令更改Android(安卓)的默认虚拟机的地址的方法

随机推荐

  1. leetcode331 验证二叉树的前序序列化 gol
  2. GoCenter 助力 Golang 全速前进
  3. 初探Kubernetes Pod
  4. 李智桦谈《 DevOps 三十六计》| 有福利
  5. Jenkinfile入门:Pipeline as code
  6. Jenkinsfile入门:Pipeline使用Maven构建j
  7. 有关Python参数的思考
  8. 代码质量管理的一些思路
  9. 基于SSM框架的JavaWeb通用权限管理系统
  10. 微服务落地反思以及有效落地