10

I know how to make rectangle with rounded corners, like this

<?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="10000dp" />
</shape>

It looks like this:

enter image description here

But I want to make the inverse of that (center transparent and sides filled with color), which should look like this:

enter image description here

Thanks

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Matej Procházka
  • 217
  • 2
  • 14

4 Answers4

10

Not proper way, but will get the result, try

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <padding
                android:bottom="-100dp"
                android:left="-100dp"
                android:right="-100dp"
                android:top="-100dp" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="200dp" />
            <stroke
                android:width="100dp"
                android:color="#FF0000" />
        </shape>
    </item>
</layer-list>
Athira
  • 1,177
  • 3
  • 13
  • 35
3

Based on: https://stackoverflow.com/a/36764393/1268507

Try with custom view:

public class CustomView extends View {
private Path mPath = new Path();

public CustomView(Context context) {
    super(context);
}

public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mPath.reset();
    mPath.addRoundRect(0, 0, getWidth(), getHeight(), 1000, 1000, Path.Direction.CW);
    mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);
    canvas.clipPath(mPath);
    canvas.drawColor(Color.parseColor("#FF0000"));
}
}

enter image description here

Alex
  • 9,102
  • 3
  • 31
  • 35
0

Check this

    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:left="5dp"
        android:top="5dp"
        android:right="5dp"
        android:bottom="5dp">
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid
                android:color="#FF0000"/>
        </shape>
    </item>
    <item
        android:left="5dp"
        android:top="5dp"
        android:right="5dp"
        android:bottom="5dp">
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid
                android:color="#FFFFFF"/>
            <corners
                android:radius="10000dp" />
        </shape>
    </item>
</layer-list>
Manish Jain
  • 2,139
  • 19
  • 15
  • What is needed is a transparent center - this is just white and would cover everything. – slott Oct 03 '19 at 09:14
0

I needed this as well so I created following Drawable class. To get the solution that is wanted for this question you can use it like following:

val radius = min(view.width, view.height)
val bg = InvertedRectDrawable(Color.RED, radius, 0)
view.background = bg

Code

import android.graphics.*
import android.graphics.drawable.Drawable

class InvertedRectDrawable(
    private val color: Int,
    private val cornerRadius: Int,
    private val border: Int,
    private val contentColor: Int? = null
) : Drawable() {

    private var paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        this.color = this@InvertedRectDrawable.color
    }
    private var paint2: Paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        contentColor?.let {
            this.color = it
        }
    }
    private val path = Path()

    override fun draw(canvas: Canvas) {
        path.reset()
        path.addRoundRect(
            border.toFloat(),
            border.toFloat(),
            bounds.width().toFloat() - 2 * border.toFloat(),
            bounds.height().toFloat() - 2 * border.toFloat(),
            cornerRadius.toFloat(),
            cornerRadius.toFloat(),
            Path.Direction.CW
        )
        path.fillType = Path.FillType.INVERSE_EVEN_ODD

        val s = canvas.save()
        canvas.clipPath(path)
        canvas.drawPaint(paint)

        contentColor?.let {

            canvas.restoreToCount(s)

            path.fillType = Path.FillType.EVEN_ODD
            canvas.clipPath(path)
            canvas.drawPaint(paint2)
        }
    }

    override fun setAlpha(alpha: Int) {
        paint.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        paint.colorFilter = colorFilter
    }

    override fun getOpacity(): Int {
        return PixelFormat.TRANSLUCENT
    }
}
prom85
  • 16,896
  • 17
  • 122
  • 242