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
however what i'm getting through my code is as follows
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)
}
}

