Custom border layout contains half of a circle

272 Views Asked by At

I need create xml with two layout title and description. In title layout I need add border have half of circle in bottom left and right, and with description layout border have half of circle in top left and right. Here is my design

enter image description here

I can do it with create two half circle over line of rectangle radius border, but I don't want use this. How I can do it with another solution? Please give me key work or solution to do it! Thank you so much!

1

There are 1 best solutions below

0
On BEST ANSWER

You can use the ShapeAppearanceModel defining a custom CornerTreatment to apply to the components. Something like:

    val radius = resources.getDimension(R.dimen.default_corner_radius)
    val title_layout = findViewById<LinearLayout>(R.id.title_layout)
    
    val titleShapeModel = ShapeAppearanceModel().toBuilder()
            .setTopLeftCorner(CornerFamily.ROUNDED, radius)
            .setTopRightCorner(CornerFamily.ROUNDED, radius)
            .setBottomLeftCorner(ConcaveRoundedCornerTreatment()).setBottomLeftCornerSize(radius)
            .setBottomRightCorner(ConcaveRoundedCornerTreatment()).setBottomRightCornerSize(radius)
            .build()
    val titleBackground = MaterialShapeDrawable(titleShapeModel)
    titleBackground.setStroke(1f, ContextCompat.getColor(this, R.color.colorPrimaryDark))

    ViewCompat.setBackground(title_layout, titleBackground)

where the ConcaveRoundedCornerTreatment is:

class ConcaveRoundedCornerTreatment : CornerTreatment() {

    override fun getCornerPath(
            shapePath: ShapePath,
            angle: Float,
            interpolation: Float,
            radius: Float
    ) {
        val interpolatedRadius = radius * interpolation
        shapePath.reset(0f, interpolatedRadius, ANGLE_LEFT, ANGLE_LEFT - angle)
        shapePath.addArc(
                -interpolatedRadius,
                -interpolatedRadius,
                interpolatedRadius,
                interpolatedRadius,
                ANGLE_BOTTOM,
                -angle
        )
    }

    companion object {
        const val ANGLE_LEFT = 180f
        const val ANGLE_BOTTOM = 90f
    }
}

Just do the same with the description layout:

enter image description here

If you are using a view like a CardView which has a built-in shapeAppearanceModel:

cardView.shapeAppearanceModel = cardView.shapeAppearanceModel.toBuilder()
        .setTopRightCorner(concaveRoundedCornerTreatment).
        .........
        .build()