Custom View Seekbar in android

84 views Asked by At

i am working on a custom view for my android application. i am trying to create a custom view for my seekbar. i have extended my custom view class from androidx.appcompat.widget.AppCompatSeekBar

However i'm not getting any success to get my exact design. the design i need is as follows

enter image description here

however what i'm getting through my code is as follows

enter image description here

here is my code

 override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)

    val totalWidth = width.toFloat()
    val totalHeight = height.toFloat()
    val segmentWidth = totalWidth / colors.size
    val verticalPaddingPercent = 0.4f // Increase this value to adjust padding

    val paddingHeight = totalHeight * verticalPaddingPercent

    val thumbHeight = totalHeight - 2 * paddingHeight
    val thumbWidth = thumb?.intrinsicWidth ?: 0 // Get thumb drawable width

    // Calculate thumb position outside of the other drawables
    val thumbTopOffset = thumbHeight * 0.2f // Offset of 10% of thumb height
    val thumbBottomOffset = thumbHeight * 0.2f // Offset of 10% of thumb height
    val thumbTop = thumbTopOffset
    val thumbBottom = totalHeight - thumbBottomOffset
    val range = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        max - min
    } else {
        TODO("TBD")
    }
    val adjustedProgress = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        progress - min
    } else {
        TODO("VERSION.SDK_INT < O")
    }
    thumbLeft = (paddingStart + (width - paddingStart - paddingEnd - thumbWidth) * adjustedProgress / range).toFloat()

    // Calculate the starting point of the text box
    val text = "This is test" // Text for the text box
    val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        textSize = 12f//resources.getDimension(R.dimen.text_size) // Define your desired text size
        color = Color.BLACK // Define your desired text color
    }
    val textWidth = textPaint.measureText(text)
    val textHeight = textPaint.fontMetrics.bottom - textPaint.fontMetrics.top

    val textBoxWidth = textWidth + 40 // Adding padding for the text box
    val textBoxLeft = thumbLeft - textBoxWidth / 2
    val textBoxTop = paddingHeight - (textHeight + 40) - 10 // Adjust this value as needed

    // Draw rectangles
    for (i in colors.indices) {
        val left = i * segmentWidth
        val right = (i + 1) * segmentWidth

        val spacing = segmentWidth * spacingFactor

        // Calculate top and bottom based on available height and padding
        val top = paddingHeight
        val bottom = top + thumbHeight

        // Draw color segment or rounded segment
        if (i == 0 || i == colors.size - 1) {
            val rectF = RectF(left, top, right - spacing, bottom)
            val path = Path()
            val cornerRadius = resources.getDimension(R.dimen.rounded_corner_radius)

            if (i == 0) {
                path.addRoundRect(rectF, floatArrayOf(cornerRadius, cornerRadius, 0f, 0f, 0f, 0f, cornerRadius, cornerRadius), Path.Direction.CW)
            } else {
                path.addRoundRect(rectF, floatArrayOf(0f, 0f, cornerRadius, cornerRadius, cornerRadius, cornerRadius, 0f, 0f), Path.Direction.CW)
            }

            canvas.drawPath(path, colors[i])
        } else {
            canvas.drawRect(left, top, right - spacing, bottom, colors[i])
        }
    }

    // Draw the rectangular square box with rounded corners and black boundary
    val textBoxRect = RectF(textBoxLeft, textBoxTop, textBoxLeft + textBoxWidth, textBoxTop + textHeight + 40)
    val textBoxPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.WHITE // White background color
        style = Paint.Style.FILL
    }
    val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLACK // Black border color
        style = Paint.Style.STROKE
        strokeWidth = 2f // Define your desired border width
    }
    canvas.drawRoundRect(textBoxRect, 10f, 10f, textBoxPaint)
    canvas.drawRoundRect(textBoxRect, 10f, 10f, borderPaint)

    // Draw the inverted triangle cutout
    val pointerPath = Path().apply {
        moveTo(thumbLeft, textBoxTop + textHeight + 40)
        lineTo(thumbLeft - 20f, textBoxTop + textHeight + 40 - 20f) // Adjust these values to position the triangle
        lineTo(thumbLeft + 20f, textBoxTop + textHeight + 40 - 20f) // Adjust these values to position the triangle
        close()
    }
    canvas.drawPath(pointerPath, textBoxPaint)

    // Draw the text
    canvas.drawText(text, textBoxLeft + 20, textBoxTop + textHeight + 20, textPaint)

    // Draw thumb drawable
    thumb?.let { thumbDrawable ->
        thumbDrawable.setBounds(thumbLeft.toInt(), thumbTop.toInt(), thumbLeft.toInt() + thumbWidth, thumbBottom.toInt())
        thumbDrawable.draw(canvas)
    }
}
0

There are 0 answers