You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin实现反向圆角求助:LayerList语法疑问

Android Kotlin 实现反向圆角效果

方法一:使用 LayerList 实现

适合静态场景,通过两层叠加实现凹口效果:

  1. 创建 drawable 文件 reverse_corner_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 底层:带圆角的基础背景 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF" />
            <corners android:radius="16dp" /> <!-- 全局圆角半径 -->
        </shape>
    </item>

    <!-- 上层:底部中间的遮挡矩形,形成反向凹口 -->
    <item
        android:height="16dp" <!-- 高度与圆角半径一致 -->
        android:gravity="bottom"
        android:left="48dp" <!-- 左右边距控制凹口宽度 -->
        android:right="48dp">
        <shape android:shape="rectangle">
            <solid android:color="#F5F5F5" /> <!-- 填入父布局的背景色 -->
        </shape>
    </item>
</layer-list>
  1. 设置背景:
  • XML 布局:
<View
    android:id="@+id/customView"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:background="@drawable/reverse_corner_bg" />
  • Kotlin 代码:
customView.background = resources.getDrawable(R.drawable.reverse_corner_bg, null)

方法二:自定义 Drawable 实现(动态可调)

需要动态修改凹口大小、圆角半径时用这种方式:

  1. 创建 ReverseCornerDrawable.kt:
class ReverseCornerDrawable(
    private val bgColor: Int,
    private val cornerRadius: Float,
    private val notchWidth: Float,
    private val notchHeight: Float
) : Drawable() {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = bgColor
        style = Paint.Style.FILL
    }

    override fun draw(canvas: Canvas) {
        val width = bounds.width().toFloat()
        val height = bounds.height().toFloat()
        val path = Path()

        // 左上角圆角
        path.moveTo(cornerRadius, 0f)
        path.arcTo(0f, 0f, cornerRadius * 2, cornerRadius * 2, 180f, 90f, false)
        // 顶部直线到凹口左边缘
        val notchLeft = (width - notchWidth) / 2
        path.lineTo(notchLeft, 0f)
        // 反向凹口圆角
        path.arcTo(
            notchLeft, 0f,
            notchLeft + notchWidth, notchHeight,
            0f, -180f, false
        )
        // 顶部直线到右上角
        path.lineTo(width - cornerRadius, 0f)
        // 右上角圆角
        path.arcTo(width - cornerRadius * 2, 0f, width, cornerRadius * 2, 270f, 90f, false)
        // 右侧直线到底部
        path.lineTo(width, height - cornerRadius)
        // 右下角圆角
        path.arcTo(width - cornerRadius * 2, height - cornerRadius * 2, width, height, 0f, 90f, false)
        // 底部直线到左下角
        path.lineTo(cornerRadius, height)
        // 左下角圆角
        path.arcTo(0f, height - cornerRadius * 2, cornerRadius * 2, height, 90f, 90f, false)
        // 左侧直线到左上角
        path.lineTo(0f, cornerRadius)
        path.close()

        canvas.drawPath(path, paint)
    }

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

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

    override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
}
  1. 在代码中使用:
val reverseDrawable = ReverseCornerDrawable(
    bgColor = Color.WHITE,
    cornerRadius = resources.getDimension(R.dimen.corner_radius_16dp),
    notchWidth = resources.getDimension(R.dimen.notch_width_96dp),
    notchHeight = resources.getDimension(R.dimen.corner_radius_16dp)
)
customView.background = reverseDrawable

内容的提问来源于stack exchange,提问作者Pankaj Sah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:26:16