如何制作一个倒圆角的矩形?
How to make a rectangle with inverted rounded corners?
我知道如何制作带圆角的矩形,像这样
<?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>
看起来像这样:
但我想制作相反的效果(中心 透明 并且侧面填充颜色),应该如下所示:
谢谢
检查这个
<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>
基于:
尝试使用自定义视图:
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"));
}
}
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>
我也需要这个,所以我创建了以下 Drawable
class。要获得此问题所需的解决方案,您可以按如下方式使用它:
val radius = min(view.width, view.height)
val bg = InvertedRectDrawable(Color.RED, radius, 0)
view.background = bg
代码
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
}
}
我知道如何制作带圆角的矩形,像这样
<?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>
看起来像这样:
但我想制作相反的效果(中心 透明 并且侧面填充颜色),应该如下所示:
谢谢
检查这个
<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>
基于:
尝试使用自定义视图:
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"));
}
}
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>
我也需要这个,所以我创建了以下 Drawable
class。要获得此问题所需的解决方案,您可以按如下方式使用它:
val radius = min(view.width, view.height)
val bg = InvertedRectDrawable(Color.RED, radius, 0)
view.background = bg
代码
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
}
}