Files
MrleeAdmin/frontend/app/uni_modules/mas-code-scan/utssdk/app-android/ContinuousSuccessOverlayView.kt
T

97 lines
3.6 KiB
Kotlin

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)
}
}