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

如何用CardView实现带透明曲线的Android UI组件?

问题描述

透明曲线效果的UI项

我想要创建图中这类UI项,尝试使用CardView但无法实现透明曲线效果。
我试过使用透明的可塑形曲线图片,但没有效果。
请问这在Android中是否可行?我在Dribbble上见过该UI,但目前没有相关解决方案或文章。CardView并非必需,但作为RecyclerView的复用组件会更合适。

解决方案

当然可行,以下几种方案可以实现这种透明曲线效果:

1. 用ShapeableImageView配合自定义路径

借助AndroidX的ShapeableImageView,通过自定义Path绘制底部透明曲线,容器背景色透过曲线区域显示底层内容。示例代码如下:

// 布局中定义控件
<androidx.appcompat.widget.AppCompatImageView
    android:id="@+id/curveContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/card_bg" />

// 代码中设置曲线路径
val width = curveContainer.width
val height = curveContainer.height
val path = Path().apply {
    moveTo(0f, 0f)
    lineTo(0f, height.toFloat())
    // 调整贝塞尔曲线控制点,适配你需要的弧度
    cubicTo(width * 0.25f, height.toFloat(), width * 0.75f, 0f, width.toFloat(), height.toFloat())
    lineTo(width.toFloat(), 0f)
    close()
}

val shapeModel = ShapeAppearanceModel.builder()
    .setBottomEdge(object : EdgeTreatment() {
        override fun getEdgePath(length: Float, center: Float, interpolation: Float, path: Path) {
            path.reset()
            path.moveTo(0f, 0f)
            cubicTo(length * 0.25f, 0f, length * 0.75f, -height.toFloat(), length, 0f)
        }
    })
    .build()

curveContainer.shapeAppearanceModel = shapeModel

2. 自定义View绘制曲线背景

创建继承自View的自定义控件,在onDraw中直接绘制带透明曲线的背景,逻辑更灵活:

class CurveCardView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = ContextCompat.getColor(context, R.color.card_bg)
    }
    private val curvePath = Path()
    private var viewHeight = 0

    init {
        attrs?.let {
            val ta = context.obtainStyledAttributes(it, R.styleable.CurveCardView)
            bgPaint.color = ta.getColor(R.styleable.CurveCardView_bgColor, bgPaint.color)
            ta.recycle()
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        viewHeight = h
        curvePath.reset()
        curvePath.moveTo(0f, 0f)
        curvePath.lineTo(0f, h.toFloat())
        curvePath.cubicTo(w * 0.25f, h.toFloat(), w * 0.75f, 0f, w.toFloat(), h.toFloat())
        curvePath.lineTo(w.toFloat(), 0f)
        curvePath.close()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawPath(curvePath, bgPaint)
    }
}

在布局里用这个自定义View作为RecyclerView Item的容器,内部添加文本、图标等元素即可,复用逻辑和普通View完全一致。

3. XML形状资源(适合简单固定曲线)

如果曲线样式固定且简单,可直接用shape资源定义,但复杂弧度难精确控制(API 24+支持百分比参数):

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/card_bg" />
    <path
        android:fillColor="@color/card_bg"
        android:pathData="M0,0 L0,H C0.25W,H 0.75W,0 W,H LW,0 Z" />
</shape>

将W、H替换为具体数值或百分比(如100%w),直接作为View的背景使用。

内容的提问来源于stack exchange,提问作者Adit Chauhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 17:37:16