Android中如何创建带有凹面的Shape图形
Hey there! 虽然看不到你提到的目标图形,但从你说普通圆角不是需求来看,大概率是那种非对称圆角、斜切角或者其他特殊异形吧?我给你整理几种常见场景的实现方案,你可以对照着试试:
自定义特殊形状的几种实现方案
1. 仅部分角为圆角(非对称圆角)
如果你的需求是只有特定几个角是圆角(比如左上+右下圆角,其余直角),直接修改你现有的<shape>标签就行,不用统一设置所有角的半径:
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FFFFFF"/> <!-- 单独设置每个角的半径,不需要圆角的设为0dp即可 --> <corners android:topLeftRadius="10dp" android:topRightRadius="0dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="10dp"/> <!-- 注意你原来的padding属性拼写有误,修正后示例如下 --> <padding android:left="8dp" android:top="8dp" android:right="8dp" android:bottom="8dp"/> </shape>
2. 斜切角/多边形类形状
如果是类似卡片带斜切角、梯形这类形状,普通<shape>标签无法实现,推荐两种方式:
方式一:自定义Path Drawable
创建一个Kotlin/Java类继承Drawable,通过绘制自定义路径实现:
class CutCornerDrawable(private val cornerSize: Float, private val shapeColor: Int) : Drawable() { private val drawPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = shapeColor style = Paint.Style.FILL } private val shapePath = Path() override fun onBoundsChange(bounds: Rect) { super.onBoundsChange(bounds) shapePath.reset() // 示例:绘制左上角斜切的矩形 shapePath.moveTo(cornerSize, 0f) shapePath.lineTo(bounds.width().toFloat(), 0f) shapePath.lineTo(bounds.width().toFloat(), bounds.height().toFloat()) shapePath.lineTo(0f, bounds.height().toFloat()) shapePath.lineTo(0f, cornerSize) shapePath.close() } override fun draw(canvas: Canvas) { canvas.drawPath(shapePath, drawPaint) } override fun setAlpha(alpha: Int) { drawPaint.alpha = alpha } override fun setColorFilter(colorFilter: ColorFilter?) { drawPaint.colorFilter = colorFilter } override fun getOpacity(): Int = PixelFormat.TRANSLUCENT }
之后在代码里给View设置这个Drawable:
val customDrawable = CutCornerDrawable(30f, Color.WHITE) yourTargetView.background = customDrawable
方式二:使用VectorDrawable
创建res/drawable/custom_shape.xml,通过矢量图形定义路径:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="200dp" android:height="100dp" android:viewportWidth="200" android:viewportHeight="100"> <!-- pathData里的坐标可按需调整,示例为右上角斜切的矩形 --> <path android:fillColor="#FFFFFF" android:pathData="M0,0 L180,0 L200,20 L200,100 L0,100 Z"/> </vector>
3. 复杂曲线/异形(波浪边、圆弧组合等)
如果是波浪底边、不规则圆弧这类更复杂的形状,依然可以用自定义Path结合贝塞尔曲线实现,比如绘制波浪底边:
override fun onBoundsChange(bounds: Rect) { super.onBoundsChange(bounds) shapePath.reset() // 绘制顶部直线+底部波浪的形状 shapePath.moveTo(0f, 0f) shapePath.lineTo(bounds.width().toFloat(), 0f) // 用二次贝塞尔曲线绘制波浪 shapePath.quadTo(bounds.width()*0.25f, bounds.height()-10f, bounds.width()*0.5f, bounds.height()) shapePath.quadTo(bounds.width()*0.75f, bounds.height()+10f, bounds.width().toFloat(), bounds.height()) shapePath.lineTo(0f, bounds.height()) shapePath.close() }
如果能补充一下目标图形的具体描述(比如是斜切角、单边波浪还是其他样式),可以给你更精准的代码哦!
内容的提问来源于stack exchange,提问作者Vala Ahmeti
相关产品推荐
相关产品推荐

