Search code examples
javaandroidandroid-layoutandroid-canvasellipse

Is there any way to create half moon like multiple circle one inside another in android xml


To achieve three semi circle

In above image i want to create three ellipse one inside another and on top one half semicircle to right end in xml android so how to achieve this and i have searched on net that with the help of canvas we can do so but i don't know how to do, please help me as it's very hard design given to me to make in android.

i have tried using by changing it's height and width but didn't get close to what is in image .


Solution

  • This is a simple custom view that will give you this shape you need to complete it and add more methods for customization for example colors, progress, margins ...etc

    import android.content.Context
    import android.graphics.Canvas
    import android.graphics.Color
    import android.graphics.Paint
    import android.graphics.RectF
    import android.util.AttributeSet
    import android.view.View
    
    class SemiCircleView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
    ) : View(context, attrs, defStyleAttr) {
    
        private val dividerProgressPaint: Paint = Paint()
        private val currentProgressPaint: Paint = Paint()
        private val remainProgressPaint: Paint = Paint()
        private val innerProgressPaint: Paint = Paint()
        private var outerRectangle: RectF? = null
        private var innerRectangle: RectF? = null
        private var margin: Float
    
        private var progressDivider = .02f
        private var progress: Float = .2f
        private var remainProgress = 1 - progress - progressDivider
    
        init {
            dividerProgressPaint.color = Color.WHITE
            dividerProgressPaint.style = Paint.Style.STROKE
            dividerProgressPaint.strokeWidth = 5f
    
            remainProgressPaint.color = Color.GREEN
            remainProgressPaint.style = Paint.Style.STROKE
            remainProgressPaint.strokeWidth = 5f
    
            currentProgressPaint.color = Color.RED
            currentProgressPaint.style = Paint.Style.STROKE
            currentProgressPaint.strokeWidth = 5f
    
            innerProgressPaint.color = Color.WHITE
            innerProgressPaint.style = Paint.Style.STROKE
            innerProgressPaint.strokeWidth = 5f
    
            margin = 50f
        }
    
        override fun onDraw(canvas: Canvas) {
            super.onDraw(canvas)
            if (outerRectangle == null) {
                outerRectangle = RectF(0f + margin, 0f + margin, width.toFloat() - margin, width.toFloat() - margin)
            }
    
            if (innerRectangle == null) {
                innerRectangle = RectF(100f, 100f, width.toFloat() - 100f , width.toFloat() - 100f)
            }
    
            val remainEndAngel = 180 + remainProgress * 180
            canvas.drawArc(outerRectangle!!, 180f, remainProgress * 180, false, remainProgressPaint)
    
            val dividerEndAngel = remainEndAngel + progressDivider * 180f
            canvas.drawArc(outerRectangle!!, remainEndAngel, progressDivider * 180f, false, dividerProgressPaint)
    
            canvas.drawArc(outerRectangle!!,dividerEndAngel, progress * 180f, false, currentProgressPaint)
    
            canvas.drawArc(innerRectangle!!, 180f, 180f, false, innerProgressPaint)
        }
    
    

    The view will look like this without any customization

    enter image description here