【问题标题】:How to make a rectangle with inverted rounded corners?如何制作一个倒圆角的矩形?
【发布时间】:2019-05-07 21:16:52
【问题描述】:

我知道如何制作圆角矩形,像这样

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

看起来像这样:

但我想将其反转(中心透明和填充颜色的侧面),应该是这样的:

谢谢

【问题讨论】:

  • 你为什么不把背景设置为红色并将圆圈颜色更改为白色。
  • @SathyaBaman 也许,因为 white != transparent
  • 同意........
  • 对我来说,使用 XML 看起来是不可能的

标签: android layout background shapes


【解决方案1】:

方法不对,但会得到结果,试试

<?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如何产生一个被粉红色框架包围的透明胶囊?
  • 诀窍在于负填充和圆角半径,您可以调整这些值以获得应得的结果
  • 请注意,如果您使用此方法,并对您的可绘制对象应用着色/过滤器,您将失去框架
【解决方案2】:

基于:https://stackoverflow.com/a/36764393/1268507

尝试自定义视图:

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"));
}
}

【讨论】:

    【解决方案3】:

    检查一下

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

    【讨论】:

    • 所需要的是一个透明的中心 - 这只是白色的,可以覆盖一切。
    【解决方案4】:

    我也需要这个,所以我创建了 Drawable 类。要获得此问题所需的解决方案,您可以使用它,如下所示:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      相关资源
      最近更新 更多