简体   繁体   中英

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?

在此输入图像描述

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> 

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>

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>

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 .

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.

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

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>

定义高度并使半径为半高。

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

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
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM