How to create following types of layout in android

42 Views Asked by At

I have tried using ProgressBar or SeekBar but how to add left cut on one side and right side also

enter image description here

1

There are 1 best solutions below

0
Payam Monsef On

I've created a sample custom ConstraintLayout for you to achive what you want.it will behave as a regular constraintLayout but just with a custom background shape.

you have to change numbers and logic according to ui ofcourse, but it will cut your imageView inside it and you can also put progressbar and textViews to create your own ui

package com.customView

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout


/**
 * Created by Payam Monsef
 * At: 2022/Jun/27
 */
class CustomConstraintLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs) {

    private var strokeWidth = 4F
    private var strokeColor = Color.CYAN
    private val cutPosition = CutPosition.TOP_LEFT

    //like 0.2 of width will be reduced from cut position
    private val reduceWidthMultiplier = 0.2

    private var mPath: Path? = null
    private var mPathBorder: Path? = null
    private var mPaint: Paint? = null

    init {
        mPath = Path()
        mPathBorder = Path()
        mPaint = Paint()
        mPaint?.style = Paint.Style.STROKE
        mPaint?.color = strokeColor
        mPaint?.strokeWidth = strokeWidth
        setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        val mW = width.toFloat()
        val mH = height.toFloat()

        mPathBorder?.apply {
            reset()
            if (cutPosition == CutPosition.BOTTOM_RIGHT) {
                moveTo(0F, 0F)
                lineTo(mW, 0F)
                lineTo(mW - (reduceWidthMultiplier * mW).toFloat(), mH)
                lineTo(0F, mH)
                close()
            } else {
                moveTo((reduceWidthMultiplier * mW).toFloat(), 0F)
                lineTo(mW, 0F)
                lineTo(mW, mH)
                lineTo(0F, mH)
                close()
            }
        }
        val offset = strokeWidth / 2
        mPath?.apply {
            reset()
            if (cutPosition == CutPosition.BOTTOM_RIGHT) {
                moveTo(offset, offset)
                lineTo(mW - offset, offset)
                lineTo(mW - (reduceWidthMultiplier * mW).toFloat(), mH - offset)
                lineTo(offset, mH - offset)
                close()
            } else {
                moveTo((reduceWidthMultiplier * mW).toFloat() , offset)
                lineTo(mW - offset, offset)
                lineTo(mW - offset, mH - offset)
                lineTo(offset, mH - offset)
                close()
            }
        }
    }

    override fun onDraw(canvas: Canvas) {
        mPathBorder?.let { p ->
            mPaint?.let { paint ->
                canvas.drawPath(p, paint)
            }
        }
        mPath?.let {
            canvas.clipPath(it)
        }
    }

    private enum class CutPosition {
        TOP_LEFT, BOTTOM_RIGHT
    }
}

Its better than you define above variables as custom attributes.you can read the Google documents to do that