diff --git a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt index 3166daa..1fc8b9c 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt @@ -905,62 +905,11 @@ class MainScreenPresentation( displayOrientation: Int, scale: Float ): ViewGroup.LayoutParams { -// val layoutParams = previewView.layoutParams -// val measuredWidth = previewView.measuredWidth -// val measuredHeight = previewView.measuredHeight -// var ratio = (previewSize.height.toFloat()) / previewSize.width.toFloat() -// if (ratio > 1) { -// ratio = 1 / ratio -// } -// if (displayOrientation % 180 == 0) { -// layoutParams.width = measuredWidth -// layoutParams.height = (measuredWidth * ratio).toInt() -// } else { -// layoutParams.height = measuredHeight -// layoutParams.width = (measuredHeight * ratio).toInt() -// } -// if (scale < 1f) { -// val rgbParam = rgbPreview.layoutParams -// layoutParams.width = (rgbParam.width * scale).toInt() -// layoutParams.height = (rgbParam.height * scale).toInt() -// } else { -// layoutParams.width = (layoutParams.width * scale).toInt() -// layoutParams.height = (layoutParams.height * scale).toInt() -// } -// -// val metrics = DisplayMetrics() -// activity.windowManager.defaultDisplay.getMetrics(metrics) -// -// if (layoutParams.width >= metrics.widthPixels) { -// val viewRatio = layoutParams.width / (metrics.widthPixels.toFloat()) -// layoutParams.width = (layoutParams.width / viewRatio).toInt() -// layoutParams.height = (layoutParams.height / viewRatio).toInt() -// } -// if (layoutParams.height >= metrics.heightPixels) { -// val viewRatio = layoutParams.height / (metrics.heightPixels.toFloat()) -// layoutParams.width = (layoutParams.width / viewRatio).toInt() -// layoutParams.height = (layoutParams.height / viewRatio).toInt() -// } - -// Timber.tag(TAG).d("initRgbCamera:metrics(${metrics.widthPixels},${metrics.heightPixels})") - - - //val layoutParams = previewView.layoutParams - //layoutParams.width = 1024 - //layoutParams.height = 768 -// val w = 600.dp //(912.dp * scale).toInt() -// val h = 900.dp //684.dp -// val w = 500.dp -// val h = 850.dp val w = 600.dp val h = 1068.dp - //(1024*scale).toInt() val layoutParams = FrameLayout.LayoutParams(w, h); -// val layoutParams = FrameLayout.LayoutParams(480, 320); -// val layoutParams = FrameLayout.LayoutParams(912.dp, 684.dp); previewView.setLayoutParams(layoutParams) faceRectView.setLayoutParams(layoutParams) - return layoutParams } diff --git a/app/src/main/java/com/sw/dualscreen/presentation/pay/FacePayPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/pay/FacePayPresentation.kt index e85db20..d295c8a 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/pay/FacePayPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/pay/FacePayPresentation.kt @@ -280,58 +280,9 @@ class FacePayPresentation( displayOrientation: Int, scale: Float ): ViewGroup.LayoutParams { -// val layoutParams = previewView.layoutParams -// val measuredWidth = previewView.measuredWidth -// val measuredHeight = previewView.measuredHeight -// var ratio = (previewSize.height.toFloat()) / previewSize.width.toFloat() -// if (ratio > 1) { -// ratio = 1 / ratio -// } -// if (displayOrientation % 180 == 0) { -// layoutParams.width = measuredWidth -// layoutParams.height = (measuredWidth * ratio).toInt() -// } else { -// layoutParams.height = measuredHeight -// layoutParams.width = (measuredHeight * ratio).toInt() -// } -// if (scale < 1f) { -// val rgbParam = rgbPreview.getLayoutParams() -// layoutParams.width = (rgbParam.width * scale).toInt() -// layoutParams.height = (rgbParam.height * scale).toInt() -// } else { -// layoutParams.width = (layoutParams.width * scale).toInt() -// layoutParams.height = (layoutParams.height * scale).toInt() -// } -// -// val metrics = DisplayMetrics() -// activity.windowManager.defaultDisplay.getMetrics(metrics) -// -// if (layoutParams.width >= metrics.widthPixels) { -// val viewRatio = layoutParams.width / (metrics.widthPixels.toFloat()) -// layoutParams.width = (layoutParams.width / viewRatio).toInt() -// layoutParams.height = (layoutParams.height / viewRatio).toInt() -// } -// if (layoutParams.height >= metrics.heightPixels) { -// val viewRatio = layoutParams.height / (metrics.heightPixels.toFloat()) -// layoutParams.width = (layoutParams.width / viewRatio).toInt() -// layoutParams.height = (layoutParams.height / viewRatio).toInt() -// } - - -// val layoutParams = previewView.layoutParams -// layoutParams.width = (608.dp * 1.5).roundToInt() -// layoutParams.height = (456.dp * 1.5).roundToInt() -// layoutParams.width = (608.dp * 1.5).roundToInt() -// layoutParams.height = (456.dp * 1.5).roundToInt() -// layoutParams.width = 1024 -// layoutParams.height = 768 -// val w = 500.dp -// val h = 850.dp - val w = 600.dp + val w = (600.dp * 1.5).toInt() val h = 1068.dp -// val w = 720.dp -// val h = 1280.dp - val layoutParams = FrameLayout.LayoutParams(w, h); + val layoutParams = FrameLayout.LayoutParams(w, h) previewView.setLayoutParams(layoutParams) faceRectView.setLayoutParams(layoutParams) @@ -472,9 +423,10 @@ class FacePayPresentation( ) irFaceRectTransformer = FaceRectTransformer( -// previewSizeIr.width, previewSizeIr.height, + previewSizeIr.width, previewSizeIr.height, +// layoutParams.width, layoutParams.height, layoutParams.width, layoutParams.height, - layoutParams.width, layoutParams.height, displayOrientation, cameraId, isMirror, + displayOrientation, cameraId, isMirror, ConfigUtil.isDrawIrRectHorizontalMirror(context), ConfigUtil.isDrawIrRectVerticalMirror(context) ) diff --git a/app/src/main/java/com/sw/dualscreen/view/HollowOvalInRectView.kt b/app/src/main/java/com/sw/dualscreen/view/HollowOvalInRectView.kt new file mode 100644 index 0000000..a49577f --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/view/HollowOvalInRectView.kt @@ -0,0 +1,122 @@ +package com.sw.dualscreen.view + +import androidx.core.graphics.toColorInt +import android.content.Context +import android.graphics.* +import android.util.AttributeSet +import android.view.View + +/** + * 带镂空椭圆的矩形自定义View + * 矩形尺寸:400dp × 510dp,背景色 #FFF4FAFF + * 镂空椭圆尺寸:400dp × 436dp,居中显示 + */ +class HollowOvalInRectView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) { + + // 基础尺寸配置(dp) + private val rectWidthDp = 400f // 矩形宽度 + private val rectHeightDp = 510f // 矩形高度 + private val ovalWidthDp = 400f // 椭圆宽度 + private val ovalHeightDp = 436f // 椭圆高度 + + // 转换后的像素尺寸 + private val rectWidth: Float + private val rectHeight: Float + private var ovalWidth: Float + private var ovalHeight: Float + + // 矩形背景画笔(颜色 #FFF4FAFF) + private val rectPaint = Paint().apply { + isAntiAlias = true + color = "#FFF4FAFF".toColorInt() // 矩形背景色 +// color = "#FFFFFF".toColorInt() // 矩形背景色 + style = Paint.Style.FILL + } + + // 镂空椭圆画笔(核心:DST_OUT模式实现镂空) + private val hollowOvalPaint = Paint().apply { + isAntiAlias = true + color = Color.BLACK // 颜色不影响镂空效果,仅需非透明即可 + style = Paint.Style.FILL + xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT) + } + + // 椭圆路径(复用避免重复创建) + private val ovalPath = Path() + + init { + // dp转px,保证多设备尺寸一致 + val density = resources.displayMetrics.density + rectWidth = rectWidthDp * density + rectHeight = rectHeightDp * density + ovalWidth = ovalWidthDp * density + ovalHeight = ovalHeightDp * density + + // 关键配置:关闭硬件加速保证Xfermode生效 + setLayerType(LAYER_TYPE_HARDWARE, null) + // 视图背景透明,避免干扰 + setBackgroundColor(Color.TRANSPARENT) + } + + /** + * 强制设置View尺寸为指定的矩形尺寸 + */ + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + val targetWidth = MeasureSpec.makeMeasureSpec(rectWidth.toInt(), MeasureSpec.EXACTLY) + val targetHeight = MeasureSpec.makeMeasureSpec(rectHeight.toInt(), MeasureSpec.EXACTLY) + super.onMeasure(targetWidth, targetHeight) + } + + /** + * 核心绘制逻辑:先画矩形,再画镂空椭圆 + */ + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + // 保存画布图层,确保Xfermode生效 + val layerId = canvas.saveLayer(0f, 0f, width.toFloat(), height.toFloat(), null) + + // 1. 绘制底层矩形(背景色 #FFF4FAFF) + canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), rectPaint) + + // 2. 计算椭圆居中坐标(椭圆宽度和矩形宽度一致,仅垂直居中) + val ovalTop = (rectHeight - ovalHeight) / 2 // 椭圆顶部偏移 + val ovalBottom = ovalTop + ovalHeight // 椭圆底部坐标 + + // 3. 绘制镂空椭圆(居中) + ovalPath.reset() + ovalPath.addOval( + 0f, // 左:和矩形左对齐(宽度一致) + ovalTop, // 上:垂直居中 + rectWidth, // 右:和矩形右对齐 + ovalBottom, // 下 + Path.Direction.CW + ) + canvas.drawPath(ovalPath, hollowOvalPaint) + + // 恢复画布状态 + canvas.restoreToCount(layerId) + } + + // 扩展方法:支持动态修改矩形背景色 + fun updateRectBackgroundColor(colorHex: String) { + try { + rectPaint.color = Color.parseColor(colorHex) + invalidate() // 重绘视图 + } catch (e: IllegalArgumentException) { + e.printStackTrace() + } + } + + // 扩展方法:支持动态修改椭圆尺寸(可选) + fun updateOvalSize(widthDp: Float, heightDp: Float) { + val density = resources.displayMetrics.density + ovalWidth = widthDp * density + ovalHeight = heightDp * density + invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/presentation_face_pay.xml b/app/src/main/res/layout/presentation_face_pay.xml index 49b7c19..0497b4f 100644 --- a/app/src/main/res/layout/presentation_face_pay.xml +++ b/app/src/main/res/layout/presentation_face_pay.xml @@ -69,7 +69,7 @@ + android:layout_height="510dp"> - - - - - - - - - - - - - - - - - - - - - - - - @@ -149,7 +125,7 @@ android:layout_weight="1" android:background="#FFF4FAFF" /> - @@ -165,7 +141,6 @@ - + + + + + - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/presentation_main_screen.xml b/app/src/main/res/layout/presentation_main_screen.xml index ecd00a8..2e0e279 100644 --- a/app/src/main/res/layout/presentation_main_screen.xml +++ b/app/src/main/res/layout/presentation_main_screen.xml @@ -72,23 +72,6 @@ android:src="@drawable/face_mask" android:visibility="gone" /> - - - - - - - - - - - - - - - - - - @@ -121,22 +104,15 @@ - - - - - - - + android:textSize="22sp" + tools:ignore="HardcodedText" /> + + + + + \ No newline at end of file