diff --git a/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt index bbd4ae2..74a6202 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/BaseActivity.kt @@ -4,8 +4,10 @@ import android.app.Dialog import android.content.Context import android.content.res.Configuration import android.content.res.Resources +import android.hardware.display.DisplayManager import android.os.Bundle import android.text.TextUtils +import android.view.Display import android.view.View import android.view.WindowManager import android.widget.TextView @@ -23,6 +25,12 @@ import timber.log.Timber abstract class BaseActivity : AppCompatActivity() { + + val displays: Array by lazy { + val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager + displayManager.displays + } + protected lateinit var binding: VB protected lateinit var context: Context private var mDialogWaiting: CustomDialog? = null diff --git a/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt index 4b3fe1e..73840e8 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/PayActivity.kt @@ -8,9 +8,11 @@ import com.sw.dualscreen.activity.fragment.pay.CashPayFragment import com.sw.dualscreen.activity.fragment.pay.FacePayFragment import com.sw.dualscreen.activity.fragment.pay.NumberPayFragment import com.sw.dualscreen.activity.fragment.pay.PayResultFragment -import com.sw.dualscreen.activity.fragment.pay.QrCodePayFragment +import com.sw.dualscreen.activity.fragment.pay.ScanQrCodePayFragment import com.sw.dualscreen.databinding.ActivityPayBinding import com.sw.dualscreen.model.response.FoodInfo +import com.sw.dualscreen.presentation.pay.FacePayPresentation +import com.sw.dualscreen.presentation.pay.ScanQrCodePayPresentation import com.sw.dualscreen.viewmodel.BaseViewModel import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel @@ -40,10 +42,10 @@ class PayActivity : BaseActivity() { var foodInfo: FoodInfo? = null - private var qrCodePayFragment: QrCodePayFragment? = null + private var qrCodePayFragment: ScanQrCodePayFragment? = null private var cashPayFragment: CashPayFragment? = null private var numberPayFragment: NumberPayFragment? = null - private var facePayFragment: FacePayFragment? = null + var facePayFragment: FacePayFragment? = null private var payResultFragment: PayResultFragment? = null @Suppress("DEPRECATION") @@ -53,33 +55,48 @@ class PayActivity : BaseActivity() { binding.tvFoodName.text = foodInfo?.foodName binding.include.ivPageBack.setOnClickListener { finish() } binding.include.tvPageTitle.text = "下单结算" - val payQrCodeClickListener = View.OnClickListener { - if (qrCodePayFragment == null) { - qrCodePayFragment = QrCodePayFragment() + binding.btnPayQrCode.setOnClickListener { + if (binding.btnPayQrCode.isChecked) { + return@setOnClickListener } - addFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE) - switchButton(true, false, false, false) + showScanQrCodePay() } - binding.btnPayQrCode.setOnClickListener(payQrCodeClickListener) binding.btnPayCash.setOnClickListener { + if (binding.btnPayCash.isChecked) { + return@setOnClickListener + } if (cashPayFragment == null) { cashPayFragment = CashPayFragment() } - addFragment(cashPayFragment!!, TAG_PAY_CASH) + showFragment(cashPayFragment!!, TAG_PAY_CASH) switchButton(false, true, false, false) } binding.btnPayNumber.setOnClickListener { + if (binding.btnPayNumber.isChecked) { + return@setOnClickListener + } if (numberPayFragment == null) { numberPayFragment = NumberPayFragment() } - addFragment(numberPayFragment!!, TAG_PAY_NUMBER) + showFragment(numberPayFragment!!, TAG_PAY_NUMBER) switchButton(false, false, true, false) } binding.btnPayFace.setOnClickListener { + if (binding.btnPayFace.isChecked) { + return@setOnClickListener + } showFacePay() } - payQrCodeClickListener.onClick(binding.btnPayQrCode) + showScanQrCodePay() + } + + private fun showScanQrCodePay() { + if (qrCodePayFragment == null) { + qrCodePayFragment = ScanQrCodePayFragment() + } + showFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE) + switchButton(true, false, false, false) } private fun switchButton(vararg arr: Boolean) { @@ -93,38 +110,49 @@ class PayActivity : BaseActivity() { if (facePayFragment == null) { facePayFragment = FacePayFragment() } - addFragment(facePayFragment!!, TAG_PAY_FACE) + showFragment(facePayFragment!!, TAG_PAY_FACE) switchButton(false, false, false, true) } - private fun addFragment(currentFragment: Fragment, tag: String) { + private fun showFragment(fragment: Fragment, tag: String) { runCatching { supportFragmentManager.beginTransaction().apply { - val existFragment = supportFragmentManager.findFragmentByTag(tag) - if (existFragment == null) { - add(R.id.fragmentContainerView, currentFragment, tag) - } - val fragments = supportFragmentManager.fragments - fragments.forEach { - it?.let { fragment -> - if (fragment != currentFragment) { - hide(fragment) - } - } - } - show(currentFragment) - commitAllowingStateLoss() + replace(R.id.fragmentContainerView, fragment) + commitNowAllowingStateLoss() } }.onFailure { it.printStackTrace() } } +// private fun showFragment(currentFragment: Fragment, tag: String) { +// runCatching { +// supportFragmentManager.beginTransaction().apply { +// val existFragment = supportFragmentManager.findFragmentByTag(tag) +// if (existFragment == null) { +// add(R.id.fragmentContainerView, currentFragment, tag) +// } +// val fragments = supportFragmentManager.fragments +// fragments.forEach { +// it?.let { fragment -> +// if (fragment != currentFragment) { +// hide(fragment) +// } +// } +// } +// show(currentFragment) +// commitAllowingStateLoss() +// } +// }.onFailure { +// it.printStackTrace() +// } +// } + fun showPayResult() { if (payResultFragment == null) { payResultFragment = PayResultFragment() } - addFragment(payResultFragment!!, TAG_PAY_RESULT) + showFragment(payResultFragment!!, TAG_PAY_RESULT) } override fun onDestroy() { @@ -134,5 +162,22 @@ class PayActivity : BaseActivity() { facePayFragment?.presentation?.dismiss() super.onDestroy() } + private var scanQrCodePayPresentation: ScanQrCodePayPresentation?=null + fun paySuccess() { + showFragment(PayResultFragment(),"") + if (displays.size > 1) { + scanQrCodePayPresentation = ScanQrCodePayPresentation( + activity = this, + display = displays[1], + type = 2 + ) { + scanQrCodePayPresentation?.dismiss() + }.also { +// it.foodName = foodName +// it.payAmount = payAmount + } + scanQrCodePayPresentation?.show() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/FacePayFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/FacePayFragment.kt index 8785926..a58290b 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/FacePayFragment.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/FacePayFragment.kt @@ -1,9 +1,9 @@ package com.sw.dualscreen.activity.fragment.pay +import android.graphics.Bitmap import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.activity.fragment.BaseFragment import com.sw.dualscreen.databinding.FragmentFacePayBinding -import com.sw.dualscreen.presentation.pay.CashPayPresentation import com.sw.dualscreen.presentation.pay.FacePayPresentation class FacePayFragment : BaseFragment() { @@ -37,6 +37,10 @@ class FacePayFragment : BaseFragment() { showSubScreen() } + fun loadBitmap(frame: Bitmap) { + binding.ivFaceImage.setImageBitmap(frame) + } + private fun showSubScreen() { // 查找副屏(通常索引为1) if (displays.size > 1) { @@ -45,6 +49,7 @@ class FacePayFragment : BaseFragment() { display = displays[1], userViewModel = payActivity!!.userViewModel, recognizeViewModel = payActivity!!.recognizeViewModel, +// parentTextureView = binding.parentTextureView, ) { presentation?.dismiss() }.also { diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/PayResultFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/PayResultFragment.kt index ad984a6..320a088 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/PayResultFragment.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/PayResultFragment.kt @@ -1,8 +1,14 @@ package com.sw.dualscreen.activity.fragment.pay +import android.text.Spanned +import android.text.SpannedString +import android.text.style.AbsoluteSizeSpan +import androidx.core.text.buildSpannedString +import com.sw.dualscreen.R import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.activity.fragment.BaseFragment import com.sw.dualscreen.databinding.FragmentPayResultBinding +import com.sw.dualscreen.ext.load class PayResultFragment: BaseFragment() { @@ -10,20 +16,25 @@ class PayResultFragment: BaseFragment() { return FragmentPayResultBinding.inflate(layoutInflater) } - private var payActivity: PayActivity? = null override fun initialize() { payActivity = activity as PayActivity binding.btnBack.setOnClickListener { - payActivity?.showFacePay() + //payActivity?.showFacePay() } + + binding.ivHeadPic.load(R.mipmap.ic_launcher) + binding.tvUserName.text = "张三" + binding.tvUserPhone.text = "132****5678" + binding.tvUserBalance.text = getBalanceText("0.00") + binding.tvPayAmount.text = "收款金额 20.00 元" + binding.tvPayInfo.text = "应收 38.00 元,余额扣除 16.80 元" } - override fun onHiddenChanged(hidden: Boolean) { - super.onHiddenChanged(hidden) - //显示时重新查询接口 - if (hidden.not()) { - + private fun getBalanceText(amount: String): SpannedString { + return buildSpannedString { + append("¥", AbsoluteSizeSpan(20, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(amount, AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/QrCodePayFragment.kt b/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/ScanQrCodePayFragment.kt similarity index 81% rename from app/src/main/java/com/sw/dualscreen/activity/fragment/pay/QrCodePayFragment.kt rename to app/src/main/java/com/sw/dualscreen/activity/fragment/pay/ScanQrCodePayFragment.kt index 2ee978e..22abe12 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/QrCodePayFragment.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/fragment/pay/ScanQrCodePayFragment.kt @@ -8,22 +8,25 @@ import androidx.lifecycle.lifecycleScope import com.sw.dualscreen.R import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.activity.fragment.BaseFragment -import com.sw.dualscreen.databinding.FragmentQrcodePayBinding import com.sw.dualscreen.ext.load -import com.sw.dualscreen.presentation.pay.QrCodePayPresentation +import com.sw.dualscreen.presentation.pay.ScanQrCodePayPresentation import com.sw.dualscreen.utils.countDownByFlow import kotlinx.coroutines.Job +import com.sw.dualscreen.databinding.FragmentScanQrcodePayBinding -class QrCodePayFragment: BaseFragment() { +class ScanQrCodePayFragment: BaseFragment() { + companion object { + + } private lateinit var payActivity: PayActivity private var foodName: String? = null private var payAmount: String? = null private var payQrCodePic: Any? = null - var presentation: QrCodePayPresentation?=null - override fun inflateViewBinding(): FragmentQrcodePayBinding { - return FragmentQrcodePayBinding.inflate(layoutInflater) + var presentation: ScanQrCodePayPresentation?=null + override fun inflateViewBinding(): FragmentScanQrcodePayBinding { + return FragmentScanQrcodePayBinding.inflate(layoutInflater) } override fun initialize() { @@ -55,7 +58,7 @@ class QrCodePayFragment: BaseFragment() { private fun showSubScreen() { // 查找副屏(通常索引为1) if (displays.size > 1) { - presentation = QrCodePayPresentation(activity = payActivity, display = displays[1]) { + presentation = ScanQrCodePayPresentation(activity = payActivity, type = 0, display = displays[1]) { presentation?.dismiss() }.also { it.foodName = foodName @@ -83,7 +86,7 @@ class QrCodePayFragment: BaseFragment() { binding.tvPayResult.text = "待支付(${seconds}s)..." }, onFinish = { - binding.tvPayResult.text = "支付倒计时结束" + binding.tvPayResult.text = "待支付" } ) } 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 6fc1345..9e94606 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt @@ -102,7 +102,7 @@ class MainScreenPresentation( binding = PresentationMainScreenBinding.inflate(layoutInflater) setContentView(binding.root) mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0 - window?.setBackgroundDrawableResource(android.R.color.transparent) + window?.setBackgroundDrawableResource(android.R.color.white) initView() setupArcCamera() registerDataChange() @@ -713,8 +713,10 @@ class MainScreenPresentation( val layoutParams = previewView.layoutParams // layoutParams.width = (608.dp * 1.5).roundToInt() // layoutParams.height = (456.dp * 1.5).roundToInt() - layoutParams.width = (600.dp * 1.5).roundToInt() - layoutParams.height = (400.dp * 1.5).roundToInt() +// layoutParams.width = (600.dp * 1.5).roundToInt() +// layoutParams.height = (450.dp * 1.5).roundToInt() + layoutParams.width = 1024 + layoutParams.height = 768 previewView.setLayoutParams(layoutParams) faceRectView.setLayoutParams(layoutParams) return layoutParams diff --git a/app/src/main/java/com/sw/dualscreen/presentation/pay/CashPayPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/pay/CashPayPresentation.kt index 466afa8..9670c61 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/pay/CashPayPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/pay/CashPayPresentation.kt @@ -41,4 +41,9 @@ class CashPayPresentation( append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } } + + override fun onDisplayRemoved() { + super.onDisplayRemoved() + onDismissListener() + } } \ No newline at end of file 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 e059017..ceeecd9 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 @@ -1,6 +1,7 @@ package com.sw.dualscreen.presentation.pay import android.Manifest +import android.app.Dialog import android.app.Presentation import android.content.pm.PackageManager import android.graphics.Bitmap @@ -10,24 +11,26 @@ import android.os.Build import android.os.Bundle import android.text.Spanned import android.text.SpannedString +import android.text.TextUtils import android.text.style.AbsoluteSizeSpan import android.view.Display +import android.view.TextureView import android.view.View import android.view.ViewGroup import android.view.ViewTreeObserver +import android.widget.ImageView +import android.widget.TextView import androidx.annotation.RequiresApi import androidx.core.content.ContextCompat import androidx.core.text.buildSpannedString import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import com.arcsoft.face.ErrorInfo -import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.R import com.sw.dualscreen.activity.PayActivity import com.sw.dualscreen.databinding.PresentationFacePayBinding -import com.sw.dualscreen.ext.dp -import com.sw.dualscreen.presentation.MainScreenPresentation -import com.sw.dualscreen.utils.SPUtil +import com.sw.dualscreen.ext.load +import com.sw.dualscreen.view.CustomDialog import com.sw.dualscreen.viewmodel.UserViewModel import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.arcface.ConfigUtil @@ -45,13 +48,13 @@ import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import kotlinx.coroutines.launch import timber.log.Timber -import kotlin.math.roundToInt class FacePayPresentation( val activity: PayActivity, display: Display, val userViewModel: UserViewModel, val recognizeViewModel: RecognizeViewModel, +// val //parentTextureView: TextureView, private val onDismissListener: () -> Unit = {} ) : Presentation(activity, display) , ViewTreeObserver.OnGlobalLayoutListener { @@ -75,16 +78,20 @@ class FacePayPresentation( super.onCreate(savedInstanceState) binding = PresentationFacePayBinding.inflate(layoutInflater) setContentView(binding.root) - window?.setBackgroundDrawableResource(R.color.transparent) + window?.setBackgroundDrawableResource(android.R.color.white) initView() setupArcCamera() registerDataChange() + + pauseCamera() } override fun show() { super.show() - resumeCamera() + binding.root.postDelayed({ + resumeCamera() + }, 1500) } var foodName: String? = null @@ -92,6 +99,14 @@ class FacePayPresentation( private fun initView() { binding.tvFoodName.text = foodName binding.tvRealAmount.text = getAmountText(payAmount ?: "") +// binding.ivPreviewImage.let { +// it.outlineProvider = object : ViewOutlineProvider() { +// override fun getOutline(view: View, outline: Outline) { +// outline.setRoundRect(0, 0, view.width, view.height, 12f.dp) +// } +// } +// it.clipToOutline = true +// } } private fun getAmountText(amount: String): SpannedString { @@ -104,6 +119,7 @@ class FacePayPresentation( override fun onGlobalLayout() { Timber.tag(TAG).d("onGlobalLayout") binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this) + //parentTextureView.getViewTreeObserver().removeOnGlobalLayoutListener(this) openCamera() } private fun openCamera() { @@ -249,17 +265,16 @@ class FacePayPresentation( val userId = faceEntity.userName if (userId == null ) return@Observer activity.runOnUiThread { - ToastUtils.showToast("获取用户id成功") + //ToastUtils.showToast("用户人脸识别成功,挑战支付页面") + showWaitingDialog("刷脸支付中,请稍后……") + binding.root.postDelayed({ + hideWaitingDialog() + activity.paySuccess() + binding.root.postDelayed({ + dismiss() + },500) + },1500) } -// if (currentFood == null) { -// //重新识别 -// activity.runOnUiThread { -// ToastUtils.showToast("currentFood == null") -// } -// //activity.recognizeFood() -// //step1FoodRecognizing() -// return@Observer -// } // userViewModel.getUserNutritionData( // userId = userId, // foodId = currentFood!!.id!! @@ -274,6 +289,7 @@ class FacePayPresentation( private fun initArcView() { //在布局结束后才做初始化操作 binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this) + //parentTextureView.getViewTreeObserver().addOnGlobalLayoutListener(this) recognizeViewModel.getCompareResultList().getValue() } @@ -337,8 +353,10 @@ class FacePayPresentation( val layoutParams = previewView.layoutParams // layoutParams.width = (608.dp * 1.5).roundToInt() // layoutParams.height = (456.dp * 1.5).roundToInt() - layoutParams.width = (600.dp * 1.5).roundToInt() - layoutParams.height = (400.dp * 1.5).roundToInt() +// layoutParams.width = (608.dp * 1.5).roundToInt() +// layoutParams.height = (456.dp * 1.5).roundToInt() + layoutParams.width = 1024 + layoutParams.height = 768 previewView.setLayoutParams(layoutParams) faceRectView.setLayoutParams(layoutParams) return layoutParams @@ -440,6 +458,9 @@ class FacePayPresentation( .previewOn(binding.dualCameraTexturePreviewRgb) .cameraListener(cameraListener) .build() + rgbCameraHelper!!.setSurfaceFrameCallback { frame -> + activity.facePayFragment?.loadBitmap(frame) + } rgbCameraHelper!!.init() // rgbCameraHelper!!.start() } @@ -543,7 +564,6 @@ class FacePayPresentation( ) // 识别成功 binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList) - ToastUtils.showToast("识别到人脸信息") } if (facePreviewInfoList.isEmpty() || (lastFaceTrackId != facePreviewInfoList[0]!!.trackId)) { @@ -561,11 +581,30 @@ class FacePayPresentation( } } private var lastFaceTrackId: Int = -1 // 上一次的人脸信息 - - fun updateImage(bitmap: Bitmap) { - activity.runOnUiThread { - // binding.ivPreviewImage.setImageBitmap(bitmap) - } + private var mDialogWaiting:CustomDialog?=null + /** + * 显示等待提示框 + */ + fun showWaitingDialog(tip: String?): Dialog? { + hideWaitingDialog() + val view = View.inflate(activity, R.layout.dialog_waiting, null) + if (!TextUtils.isEmpty(tip)) (view.findViewById(R.id.tvTip) as TextView).text = tip + mDialogWaiting = CustomDialog(activity, view, R.style.MyDialog) + mDialogWaiting!!.show() + mDialogWaiting!!.setCancelable(true) + return mDialogWaiting } + /** + * 隐藏等待提示框 + */ + fun hideWaitingDialog() { + mDialogWaiting?.dismiss() + mDialogWaiting = null + } + + override fun onDisplayRemoved() { + super.onDisplayRemoved() + onDismissListener() + } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/presentation/pay/QrCodePayPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/pay/QrCodePayPresentation.kt deleted file mode 100644 index 1b5ea1f..0000000 --- a/app/src/main/java/com/sw/dualscreen/presentation/pay/QrCodePayPresentation.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.sw.dualscreen.presentation.pay - -import android.app.Presentation -import android.os.Bundle -import android.text.Spanned -import android.text.SpannedString -import android.text.style.AbsoluteSizeSpan -import android.view.Display -import androidx.core.text.buildSpannedString -import com.sw.dualscreen.activity.PayActivity -import com.sw.dualscreen.databinding.PresentationQrcodePayBinding -import com.sw.dualscreen.ext.load - -class QrCodePayPresentation( - val activity: PayActivity, - display: Display, - private val onDismissListener: () -> Unit = {} -) : Presentation(activity, display) { - - private lateinit var binding: PresentationQrcodePayBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = PresentationQrcodePayBinding.inflate(layoutInflater) - setContentView(binding.root) - window?.setBackgroundDrawableResource(android.R.color.transparent) - initView() - } - - var foodName: String? = null - var payAmount: String? = null - var payQrCodePic: Any? = null - private fun initView() { - binding.tvFoodName.text = foodName - binding.tvRealAmount.text = getAmountText(payAmount ?: "") - binding.ivPayQrCode.load(payQrCodePic) - } - - private fun getAmountText(amount: String): SpannedString { - return buildSpannedString { - append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/sw/dualscreen/presentation/pay/ScanQrCodePayPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/pay/ScanQrCodePayPresentation.kt new file mode 100644 index 0000000..ecbf0f1 --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/presentation/pay/ScanQrCodePayPresentation.kt @@ -0,0 +1,115 @@ +package com.sw.dualscreen.presentation.pay + +import android.app.Presentation +import android.os.Bundle +import android.text.Spanned +import android.text.SpannedString +import android.text.style.AbsoluteSizeSpan +import android.text.style.ForegroundColorSpan +import android.view.Display +import androidx.core.graphics.toColorInt +import androidx.core.text.buildSpannedString +import com.sw.dualscreen.R +import com.sw.dualscreen.activity.PayActivity +import com.sw.dualscreen.databinding.PresentationScanQrcodePayBinding +import com.sw.dualscreen.ext.gone +import com.sw.dualscreen.ext.load +import com.sw.dualscreen.ext.visible + +class ScanQrCodePayPresentation( + val activity: PayActivity, + display: Display, + val type:Int, + private val onDismissListener: () -> Unit = {} +) : Presentation(activity, display) { + + //type = 0,扫码支付默认显示二维码 + //type = 1,会员结算显示二维码,是会员则显示名字、头像、手机号、可用余额 + //type = 2,支付成功,是会员则显示名字、头像、手机号、可用余额 + + private lateinit var binding: PresentationScanQrcodePayBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = PresentationScanQrcodePayBinding.inflate(layoutInflater) + setContentView(binding.root) + window?.setBackgroundDrawableResource(android.R.color.transparent) + initView() + } + + var foodName: String? = null + var payAmount: String? = null + var payQrCodePic: Any? = null + private fun initView() { + when(type) { + 0->{ + binding.layoutVip.gone() + binding.layoutPaySuccess.gone() + binding.layoutScanQrCode.visible() + + binding.tvPayTip.text = "请扫码支付或出示付款码" + binding.tvFoodName.text = foodName + binding.tvRealAmount.text = getAmountText(payAmount ?: "") + binding.ivPayQrCode.load(payQrCodePic) + } + 1->{ + binding.layoutVip.visible() + binding.layoutPaySuccess.gone() + binding.layoutScanQrCode.visible() + + binding.tvFoodName.text = foodName + binding.tvRealAmount.text = getAmountText(payAmount ?: "") + binding.ivPayQrCode.load(payQrCodePic) + + binding.ivHeadPic.load(R.mipmap.ic_launcher) + binding.tvUserName.text = "张三" + binding.tvUserPhone.text = "132****5678" + binding.tvUserBalance.text = getBalanceText("0.00") + + binding.tvPayTip.text = getPayTip("-16.80", "22.00") + } + 2->{ + binding.layoutVip.visible() + binding.layoutPaySuccess.visible() + binding.layoutScanQrCode.gone() + + binding.ivHeadPic.load(R.mipmap.ic_launcher) + binding.tvUserName.text = "张三" + binding.tvUserPhone.text = "132****5678" + binding.tvUserBalance.text = getBalanceText("0.00") + + binding.tvPayInfo.text = "余额扣除 16.80 元,在线支付 20.00 元" + + } + } + } + + private fun getPayTip(startAmount:String, endAmount: String): SpannedString { + return buildSpannedString { + append("余额扣除 ", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(startAmount, ForegroundColorSpan("#FF0A1428".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(" 元,还需支付 ", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(endAmount, ForegroundColorSpan("#FF0A1428".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(" 元", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + } + } + + private fun getBalanceText(amount: String): SpannedString { + return buildSpannedString { + append("¥", AbsoluteSizeSpan(20, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(amount, AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + } + } + + private fun getAmountText(amount: String): SpannedString { + return buildSpannedString { + append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + } + } + + override fun onDisplayRemoved() { + super.onDisplayRemoved() + onDismissListener() + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_face_pay.xml b/app/src/main/res/layout/fragment_face_pay.xml index 3875d2b..e6596fa 100644 --- a/app/src/main/res/layout/fragment_face_pay.xml +++ b/app/src/main/res/layout/fragment_face_pay.xml @@ -17,19 +17,25 @@ - + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_pay_result.xml b/app/src/main/res/layout/fragment_pay_result.xml index bed7fc5..2d07764 100644 --- a/app/src/main/res/layout/fragment_pay_result.xml +++ b/app/src/main/res/layout/fragment_pay_result.xml @@ -22,11 +22,12 @@ android:paddingTop="32dp" android:paddingBottom="47dp"> - @@ -158,14 +159,9 @@ - - - diff --git a/app/src/main/res/layout/fragment_qrcode_pay.xml b/app/src/main/res/layout/fragment_scan_qrcode_pay.xml similarity index 100% rename from app/src/main/res/layout/fragment_qrcode_pay.xml rename to app/src/main/res/layout/fragment_scan_qrcode_pay.xml diff --git a/app/src/main/res/layout/presentation_face_pay.xml b/app/src/main/res/layout/presentation_face_pay.xml index 1b864fc..e571379 100644 --- a/app/src/main/res/layout/presentation_face_pay.xml +++ b/app/src/main/res/layout/presentation_face_pay.xml @@ -67,8 +67,8 @@ + + + + @@ -104,8 +108,8 @@ diff --git a/app/src/main/res/layout/presentation_main_screen.xml b/app/src/main/res/layout/presentation_main_screen.xml index b9e2711..6da0c35 100644 --- a/app/src/main/res/layout/presentation_main_screen.xml +++ b/app/src/main/res/layout/presentation_main_screen.xml @@ -34,7 +34,7 @@ @@ -79,13 +79,13 @@ diff --git a/app/src/main/res/layout/presentation_qrcode_pay.xml b/app/src/main/res/layout/presentation_qrcode_pay.xml deleted file mode 100644 index 5a75c15..0000000 --- a/app/src/main/res/layout/presentation_qrcode_pay.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/presentation_scan_qrcode_pay.xml b/app/src/main/res/layout/presentation_scan_qrcode_pay.xml new file mode 100644 index 0000000..f742ad0 --- /dev/null +++ b/app/src/main/res/layout/presentation_scan_qrcode_pay.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 10c9faa..e85a8ef 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -166,4 +166,10 @@ 0.5 + + + \ No newline at end of file diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/ConfigUtil.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/ConfigUtil.java index 4b20d0b..c1bc44f 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/ConfigUtil.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/ConfigUtil.java @@ -88,8 +88,10 @@ public class ConfigUtil { * 默认相机分辨率 */ // private static final String DEFAULT_PREVIEW_SIZE = "1280x720"; - private static final String DEFAULT_PREVIEW_SIZE = "600x400"; -// private static final String DEFAULT_PREVIEW_SIZE = "400x640"; +// private static final String DEFAULT_PREVIEW_SIZE = "608x456"; + private static final String DEFAULT_PREVIEW_SIZE = "1024x768"; +// private static final String DEFAULT_PREVIEW_SIZE = "800x600"; +// private static final String DEFAULT_PREVIEW_SIZE = "640x480"; /** diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/camera/DualCameraHelper.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/camera/DualCameraHelper.java index 6e4b092..f8b5825 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/camera/DualCameraHelper.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/camera/DualCameraHelper.java @@ -1,5 +1,6 @@ package com.sw.plate.utils.arcface.camera; +import android.graphics.Bitmap; import android.graphics.ImageFormat; import android.graphics.Point; import android.graphics.SurfaceTexture; @@ -42,8 +43,10 @@ public class DualCameraHelper implements Camera.PreviewCallback { private Integer specificCameraId = null; private CameraListener cameraListener; - private static final int MIN_PREVIEW_WIDTH = 720; - private static final int MIN_PREVIEW_HEIGHT = 720; +// private static final int MIN_PREVIEW_WIDTH = 720; +// private static final int MIN_PREVIEW_HEIGHT = 720; + private static final int MIN_PREVIEW_WIDTH = 800; + private static final int MIN_PREVIEW_HEIGHT = 600; private DualCameraHelper(Builder builder) { previewDisplayView = builder.previewDisplayView; @@ -60,6 +63,16 @@ public class DualCameraHelper implements Camera.PreviewCallback { } } + public interface SurfaceFrameCallback { + void onFrameCallback(Bitmap frame); + } + + private SurfaceFrameCallback surfaceFrameCallback; + + public void setSurfaceFrameCallback(SurfaceFrameCallback callback) { + this.surfaceFrameCallback = callback; + } + public void init() { if (previewDisplayView instanceof TextureView) { ((TextureView) this.previewDisplayView).setSurfaceTextureListener(textureListener); @@ -126,6 +139,12 @@ public class DualCameraHelper implements Camera.PreviewCallback { return; } List supportedPreviewSize = getCommonSupportedPreviewSize(); + StringBuilder stringBuilder = new StringBuilder(); + for (Camera.Size size : supportedPreviewSize) { + stringBuilder.append("width=").append(size.width).append(",") + .append("height=").append(size.height).append(","); + } + Log.d(TAG, "start: "+stringBuilder); //相机数量为2则打开1,1则打开0,相机ID 1为前置,0为后置 mCameraId = Camera.getNumberOfCameras() - 1; //若指定了相机ID且该相机存在,则打开指定的相机 @@ -371,7 +390,12 @@ public class DualCameraHelper implements Camera.PreviewCallback { @Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { - + if (surfaceFrameCallback!=null) { + if (previewDisplayView instanceof TextureView) { + Bitmap frame = ((TextureView) previewDisplayView).getBitmap(); + surfaceFrameCallback.onFrameCallback(frame); + } + } } }; private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {