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

如何在Android中实现带卡片镂空效果的证件拍照界面

解决方案

你现在的实现里直接叠加了一层全局半透明黑色RelativeLayout,这种方式没法直接做出区域镂空效果,推荐以下两种可行方案:

方案1:自定义镂空遮罩View(推荐,适配性最高)

你可以自定义一个View作为半透明遮罩层,替换现有单独的半透明黑色RelativeLayout,步骤如下:

  1. 新建自定义View类CameraMaskView,重写绘制逻辑:
class CameraMaskView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    // 半透明遮罩颜色,对应你原来的50%透明度黑色
    private val maskColor = Color.parseColor("#80000000")
    // 镂空卡片的圆角,可根据实际需求调整数值
    private val cornerRadius = resources.getDimension(R.dimen._8sdp)
    private val hollowRect = RectF()
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val clearXfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // 计算镂空区域位置,和你原有布局里卡片区域位置对齐
        val horizontalMargin = resources.getDimension(R.dimen._40sdp)
        val topMargin = resources.getDimension(R.dimen._120sdp)
        val cardHeight = resources.getDimension(R.dimen._150sdp)
        hollowRect.apply {
            left = horizontalMargin
            top = topMargin
            right = w - horizontalMargin
            bottom = topMargin + cardHeight
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 开启离屏缓冲,避免CLEAR模式清空底层预览内容
        setLayerType(LAYER_TYPE_HARDWARE, paint)
        // 绘制全页面半透明遮罩
        canvas.drawColor(maskColor)
        // 设置混合模式为清除,画出镂空区域
        paint.xfermode = clearXfermode
        canvas.drawRoundRect(hollowRect, cornerRadius, cornerRadius, paint)
        // 重置混合模式
        paint.xfermode = null
    }
}
  1. 替换布局中的半透明层
    把原有布局里的这段代码:
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:alpha="0.5"
    android:background="@color/black" />

替换为自定义的遮罩View:

<com.你的包名路径.CameraMaskView
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
  1. 删除冗余代码
    你原有布局里的viewFinderCard这个PreviewView是冗余的,直接删掉即可,镂空区域会直接显示底层viewFinder的摄像头预览内容。

方案2:图层拼接实现(无需自定义View,适合快速开发)

你可以用9块纯色View拼接出遮罩:上下左右四个半透明黑边,加上四个边角的半透明黑块,中间留空即为镂空区域。这种方式不需要写自定义View代码,但是适配不同屏幕尺寸时灵活性较差,调整参数的成本更高。


内容的提问来源于stack exchange,提问作者Karan Mehta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 04:57:06