package uts.sdk.modules.masCodeScan import android.content.Context import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.RectF import android.graphics.Typeface import android.view.View import kotlin.math.min /** * 连续扫码成功提示层:覆盖扫描框中部,显示成功状态和本次扫码值。 */ class ContinuousSuccessOverlayView( context: Context, private val successHint: String ) : View(context) { private val density = resources.displayMetrics.density private val scaledDensity = resources.displayMetrics.scaledDensity private val panelPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.argb(218, 48, 48, 48) style = Paint.Style.FILL } private val titlePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.WHITE textSize = 16f * scaledDensity textAlign = Paint.Align.CENTER typeface = Typeface.DEFAULT_BOLD } private val valuePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.WHITE textSize = 15f * scaledDensity textAlign = Paint.Align.CENTER } private val panelRect = RectF() private var frameRect = RectF() private var stillFrame: Bitmap? = null private var value = "" fun showSuccess(scanFrame: RectF, content: String, bitmap: Bitmap?) { stillFrame?.recycle() stillFrame = bitmap frameRect = RectF(scanFrame) value = content visibility = VISIBLE invalidate() } fun hideSuccess() { stillFrame?.recycle() stillFrame = null value = "" visibility = GONE invalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) if (value.isBlank() || width <= 0 || height <= 0) return stillFrame?.takeIf { !it.isRecycled && it.width > 0 && it.height > 0 }?.let { bitmap -> val bitmapWidth = bitmap.width.toFloat() val bitmapHeight = bitmap.height.toFloat() val scale = maxOf(width / bitmapWidth, height / bitmapHeight) val drawWidth = bitmapWidth * scale val drawHeight = bitmapHeight * scale val left = (width - drawWidth) / 2f val top = (height - drawHeight) / 2f canvas.drawBitmap(bitmap, null, RectF(left, top, left + drawWidth, top + drawHeight), null) } val availableWidth = if (frameRect.isEmpty) width.toFloat() else frameRect.width() val panelWidth = min(300f * density, maxOf(0f, availableWidth - 24f * density)) val panelHeight = 68f * density val centerX = if (frameRect.isEmpty) width / 2f else frameRect.centerX() val centerY = if (frameRect.isEmpty) height / 2f else frameRect.centerY() panelRect.set( centerX - panelWidth / 2f, centerY - panelHeight / 2f, centerX + panelWidth / 2f, centerY + panelHeight / 2f ) panelRect.left = panelRect.left.coerceAtLeast(12f * density) panelRect.right = panelRect.right.coerceAtMost(width - 12f * density) panelRect.top = panelRect.top.coerceAtLeast(24f * density) panelRect.bottom = panelRect.bottom.coerceAtMost(height - 24f * density) canvas.drawRoundRect(panelRect, 12f * density, 12f * density, panelPaint) val titleBaseline = panelRect.centerY() - 3f * density val valueBaseline = panelRect.centerY() + 19f * density canvas.drawText(successHint, panelRect.centerX(), titleBaseline, titlePaint) canvas.drawText(value, panelRect.centerX(), valueBaseline, valuePaint) } }