user1372984
user1372984

Reputation:

How can I create a rectangle with two curved sides in XML drawable?

I want the left and right sides (not the corners) of the rectangle to be curved. Or say the top and bottom sides of an oval shape straight.

How can I achieve something like this?

enter image description here

Upvotes: 19

Views: 12525

Answers (10)

hikky36
hikky36

Reputation: 355

To make the sides always stay curvy with any height, I end up have to create the shape programmatically like below (code in Kotlin)

class CurvedSidesShape : RectShape() {
    override fun draw(canvas: Canvas, paint: Paint?) {
        var path = Path()
        path.addRoundRect(rect(), rect().height(), rect().height(), Path.Direction.CW)
        canvas.drawPath(path, paint)
    }
}

and here's how I use the shape as a button background

class CurvedSidesButton : Button {
    private var mHeight: Int = 0

    constructor(context: Context?) : super(context) {
        init(context, null, 0, 0)
    }

    .
    .
    .

    override fun draw(canvas: Canvas?) {
        setCurvedSidesBackground(height)
        super.draw(canvas)
    }

    private fun setCurvedSidesBackground(height: Int) {
        if (height != mHeight) {
            val curvedSidesShape = ShapeDrawable(CurvedSidesShape())
            curvedSidesShape.intrinsicWidth = width
            curvedSidesShape.intrinsicHeight = height
            curvedSidesShape.paint.color = Color.RED
            background = curvedSidesShape
            mHeight = height
        }
    }
}

Upvotes: 0

mukedev
mukedev

Reputation: 1

You can increase the radius size to 200dp and set the drawable to textview's background

<solid android:color="#E6121A" />

<corners
    android:bottomLeftRadius="12dp"
    android:bottomRightRadius="12dp"
    android:topLeftRadius="12dp"
    android:topRightRadius="12dp" />

Upvotes: 0

Ali Gorji
Ali Gorji

Reputation: 327

It's worked fine!

<?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">

    <solid
        android:color="@color/color_red"/>
    <corners
        android:radius="10000dp" /> 
</shape>

Upvotes: 11

user1165560
user1165560

Reputation: 341

Define the height and make the radius half of the height.

Upvotes: 0

Timmy Simons
Timmy Simons

Reputation: 599

Try this on textview, for single character it will show a circle, for multiple digits it will automatically expand into the shape you showed above, but if you strictly want above shape just give larger padding on left and right

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <padding
        android:top="3dp"
        android:left="8dp"
        android:right="8dp" 
        android:bottom="3dp"/>

    <solid android:color="#E6121A" />

    <corners
        android:bottomLeftRadius="12dp"
        android:bottomRightRadius="12dp"
        android:topLeftRadius="12dp"
        android:topRightRadius="12dp" />

</shape> 

Upvotes: 14

giroxiii
giroxiii

Reputation: 685

It seems that the maximum radius allowed in the shape is half of the total height in the shape bellow, so you can use it to have a shape with flexible height that keep the desire ratio:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#ffffff" />
    <size android:height="@dimen/height" />
    <corners
        android:radius="@dimen/height"
        />
</shape>

Upvotes: 0

Caye
Caye

Reputation: 329

I arrive a bit late, and the answer must not be totally complete (i dont consider flexible heights), but at least if we know in advance the height in dp the trick is to have the radius as the half of the height of the button. For instance if the height would be 48dp, we could do something like:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#ff0000"/>
    <corners android:radius="24dp" />
</shape>

Upvotes: 5

Harshid Vasoya
Harshid Vasoya

Reputation: 5721

I think one of the best idea is create shape using xml fiel.

Create Drawable->ovalshape.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <solid android:color="#ff0000" />

    <corners
        android:bottomLeftRadius="8dp"
        android:bottomRightRadius="8dp"
        android:topLeftRadius="8dp"
        android:topRightRadius="8dp" />

    <padding
        android:bottom="5dip"
        android:left="10dip"
        android:right="10dip"
        android:top="5dip" />

</shape>

Now you can used this xml instead of image easily.I think this is helpful for you and new SO user.

Upvotes: 1

Jordi Coscolla
Jordi Coscolla

Reputation: 1066

The easy way is using a 9-patch image (an png image that ends in image.9.png) and have a extra pixel border that defines how to scale the image.

Another way is to create a shape file in the res/drawable folder just like that.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="#ff0000"/>
</shape>

more info about shapes here

Upvotes: 0

user2652246
user2652246

Reputation:

Try setting the border radius to half of the height. In CSS, border-radius:50% creates an ellipse, so I would guess that if it's only 50% of the height then you would get something like that.

Upvotes: 0

Related Questions