97 lines
3.6 KiB
Kotlin
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)
|
|
}
|
|
}
|