Kotlin - > Scope Selection Progress Bar, Two-way SeekBar

First of all, look at the trilogy of custom View.

1:onMeasure method

The main purpose of this method is based on xml
android:layout_width="wrap_content"
android:layout_height="wrap_content"

The wrap_content match_parent attributes determine the size of the measurement itself.
Of course, these two values, just parent tells you, need to be measured according to this rule, if you are a bad child, then you can ignore the measurement rules, arbitrarily set a width and height, such as: setMeasured Dimension (10,000, 20,000) is so simple;

2:onLayout method

If you're a custom View, this method doesn't need to override
If you are a custom View Group, you must override it. The purpose of this method is that you decide where the child view is on the interface.

3:onDraw method

In this way, you can expand your gifted drawing function and draw whatever you want. Beautiful view comes out like this.
Friendship Tip: If you are a custom ViewGroup, you also need to call the setWillNotDraw(false) method, otherwise the onDraw method will not execute.

Don't worry, analyse a wave:

1:There are two sliding floats.
2: A track is needed. The float slides on the track.
3: The colours between floats are different
4: Progress text on the float

There are not many steps, but they can be achieved easily.

Because it's all a draw operation, the onDraw code is pasted here directly:

onDraw

override fun onDraw(canvas: Canvas) {
   //canvas.drawColor(Color.parseColor("#80000000"))

     paint.style = Paint.Style.FILL
     paint.color = trackColor
     paint.textSize = textSize

     //Orbit mapping
     trackRectF.set((paddingLeft + thumbRadius).toFloat(), trackTop,
             measuredWidth.toFloat() - paddingRight - thumbRadius, trackTop + trackHeight)
     canvas.drawRoundRect(trackRectF, trackRoundRadius.toFloat(), trackRoundRadius.toFloat(), paint)

     //Calculating rectangular coordinate position of float
     calcThumbValueRect()

     //Drawing progress
     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)

     //Draw float
     drawThumb(canvas, minValueRectF)
     drawThumb(canvas, maxValueRectF)

     //Draw prompt text
     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)

     //Drawing Float Outer Circle
     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
     )
 }

Gesture processing:

/**Gestures are held at that point, regardless of the maximum and minimum points.*/
    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)

                    //Put it on the spot
                    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
    }

Contact author

Please use QQ scanner to add group, small partners are waiting for you!

Pay attention to my public number and play together every day!

Keywords: Android xml

Added by tskweb on Fri, 24 May 2019 02:29:22 +0300