如何在Android XML Shape中实现右上角倒圆角边框效果
实现方案
固定尺寸写死的XML layer-list方案无法适配动态宽度,推荐以下两种无硬编码的实现方式:
方案1:Kotlin自定义Drawable(兼容性最好,无额外依赖)
直接通过Canvas绘制路径,自动适配控件的实际宽高,不需要预设任何尺寸参数:
import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.RectF import android.graphics.drawable.Drawable class InvertedTopRightCornerDrawable( private val bgColor: Int, private val cornerRadius: Float // 圆角大小,单位px ) : Drawable() { private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = bgColor style = Paint.Style.FILL } private val path = Path() private val cornerRect = RectF() override fun draw(canvas: Canvas) { val width = bounds.width().toFloat() val height = bounds.height().toFloat() path.reset() // 路径起点:左上角 path.moveTo(0f, 0f) // 画到右上角圆角的左切点 path.lineTo(width - cornerRadius, 0f) // 绘制外凸的右上角圆角 cornerRect.set( width - cornerRadius * 2, 0f, width, cornerRadius * 2 ) path.arcTo(cornerRect, 270f, 90f) // 画到右下角 path.lineTo(width, height) // 画到左下角 path.lineTo(0f, height) // 闭合路径 path.close() canvas.drawPath(path, paint) } override fun setAlpha(alpha: Int) { paint.alpha = alpha } override fun setColorFilter(colorFilter: android.graphics.ColorFilter?) { paint.colorFilter = colorFilter } override fun getOpacity(): Int { return android.graphics.PixelFormat.OPAQUE } }
使用方式
直接给目标控件设置背景即可,控件宽度随内容变化时形状会自动适配:
// cornerRadius可根据需求调整,注意dp转px的转换,示例直接传px值 val drawable = InvertedTopRightCornerDrawable(Color.GREEN, 50f) yourTextView.background = drawable
方案2:使用Material Components ShapeAppearance(代码更简洁)
如果项目已经引入了Material组件库,可以直接用官方提供的形状裁剪能力,不需要自行绘制路径:
import com.google.android.material.shape.CornerFamily import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.ShapeAppearanceModel val shapeModel = ShapeAppearanceModel.builder() // 右上角设置为外凸圆角 .setTopRightCorner(CornerFamily.ROUNDED, 50f) // 其余三个角保留直角 .setTopLeftCorner(CornerFamily.ROUNDED, 0f) .setBottomLeftCorner(CornerFamily.ROUNDED, 0f) .setBottomRightCorner(CornerFamily.ROUNDED, 0f) .build() val shapeDrawable = MaterialShapeDrawable(shapeModel).apply { fillColor = android.content.res.ColorStateList.valueOf(Color.GREEN) } yourTextView.background = shapeDrawable
如果需要添加边框,两种方案都可以快速扩展:自定义Drawable可新增描边画笔实现,MaterialShapeDrawable直接设置strokeWidth和strokeColor属性即可。
内容的提问来源于stack exchange,提问作者trainmania100
相关产品推荐
相关产品推荐

