18

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

  • Is this fixed height and width? – Ted Hopp Aug 06 '13 at 03:19
  • @TedHopp not necessarily –  Aug 06 '13 at 03:20
  • I'd be tempted to play around with a layer list drawable that would have three elements: two circles at the left and right and a rectangle in the center. I'm not sure how to get it to scale properly, though. Also, let me rephrase the earlier question: is this a _known_ height? (It might be known but not fixed if, say, the height were bound to a resource that varies with device configuration.) – Ted Hopp Aug 06 '13 at 03:34
  • The gmail app shows a similarly shaped dialog at the bottom of the screen when you delete an email. I'm not sure how they shape it though. – GDanger Oct 23 '14 at 22:18

10 Answers10

14

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> 
Mika
  • 5,807
  • 6
  • 38
  • 83
Timmy Simons
  • 599
  • 8
  • 21
9

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>
Ali Gorji
  • 184
  • 3
  • 7
5

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>
Caye
  • 329
  • 4
  • 5
1

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.

Harshid
  • 5,701
  • 4
  • 37
  • 50
0

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.

0

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

Jordi Coscolla
  • 1,066
  • 6
  • 8
  • How are you going to define a 9-patch that stretches vertically in a way that preserves the rounded ends? Also, I don't think an oval will have flat top and bottom. It will be an ellipse with major and minor diameters that just fill the box, something OP explicitly said was unwanted. – Ted Hopp Aug 06 '13 at 03:25
0

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>
giroxiii
  • 655
  • 5
  • 14
0

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

user1165560
  • 331
  • 4
  • 21
0

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" />

mukedev
  • 1
  • 1
0

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
        }
    }
}
hikky36
  • 323
  • 2
  • 14