Преглед изворни кода

refactor(更新)
- 修改指纹设置页面的缺省页的展示逻辑
- 优化用户信息的头像设置的流程,新增人脸识别的绘制框和拍摄倒计时
- 修改“密码重置”为“重置密码”

周文健 пре 10 месеци
родитељ
комит
7799650822

+ 5 - 0
app/src/main/java/com/grkj/iscs/features/main/fragment/user_info/SetFingerprintFragment.kt

@@ -217,6 +217,11 @@ class SetFingerprintFragment : BaseFragment<FragmentSetFingerprintBinding>() {
 
     private fun getData() {
         viewModel.getFingerprintData().observe(this) {
+            if (viewModel.sysBiometricDataVo.isEmpty()) {
+                binding.state.showEmpty()
+            } else {
+                binding.state.showContent()
+            }
             binding.listRv.models = viewModel.sysBiometricDataVo
         }
     }

+ 66 - 27
app/src/main/java/com/grkj/iscs/features/main/fragment/user_info/UserInfoFragment.kt

@@ -12,6 +12,7 @@ import com.grkj.iscs.R
 import com.grkj.iscs.databinding.FragmentUserInfoBinding
 import com.grkj.iscs.features.main.viewmodel.user_info.UserInfoViewModel
 import com.grkj.shared.utils.ArcSoftUtil
+import com.grkj.shared.utils.CancellableTimer
 import com.grkj.ui_base.base.BaseFragment
 import com.grkj.ui_base.dialog.TipDialog
 import com.grkj.ui_base.utils.CommonUtils
@@ -30,7 +31,25 @@ import dagger.hilt.android.AndroidEntryPoint
 class UserInfoFragment : BaseFragment<FragmentUserInfoBinding>() {
     private val viewModel: UserInfoViewModel by viewModels()
     private var mCapturedBitmap: Bitmap? = null
-    private var isFaceChecking: Boolean = false
+    private var isFaceDetect: Boolean = false
+    private var isInCountDown: Boolean = false
+    private val captureTimer = CancellableTimer(4000, 1000, {
+        binding.countDownTip.text = "${(3000 - it) / 1000}"
+    }) {
+        ArcSoftUtil.inDetecting = true
+        isFaceDetect = true
+        binding.previewLayout.visibility = View.INVISIBLE
+        binding.image.visibility = View.VISIBLE
+        binding.recapture.visibility = View.VISIBLE
+        binding.setAvatarConfirm.visibility = View.VISIBLE
+        binding.countDownTip.text = getString(R.string.detect_face_tip)
+        binding.countDownTip.isVisible = false
+    }
+    private val reCaptureTimer = CancellableTimer(2000, 1000, {}) {
+        isFaceDetect = false
+        ArcSoftUtil.inDetecting = false
+        isInCountDown = false
+    }
 
     override fun getLayoutId(): Int {
         return R.layout.fragment_user_info
@@ -45,23 +64,26 @@ class UserInfoFragment : BaseFragment<FragmentUserInfoBinding>() {
             navController.popBackStack()
         }
         binding.avatar.setDebouncedClickListener {
-            binding.showUserInfoLayout.isVisible = false
             binding.faceSetLayout.isVisible = true
-            isFaceChecking = false
+            binding.image.isVisible = false
+            binding.previewLayout.isVisible = true
+            binding.setAvatarConfirm.isVisible = false
+            binding.recapture.isVisible = false
             startFace()
         }
         binding.setAvatarCancel.setDebouncedClickListener {
             releaseFace()
-            isFaceChecking = false
-            binding.showUserInfoLayout.isVisible = true
             binding.faceSetLayout.isVisible = false
+            binding.image.isVisible = false
+            binding.previewLayout.isVisible = true
+            binding.setAvatarConfirm.isVisible = false
+            binding.recapture.isVisible = false
         }
         binding.setAvatarConfirm.setDebouncedClickListener {
             releaseFace()
-            isFaceChecking = false
-            binding.avatar.load(mCapturedBitmap)
-            binding.showUserInfoLayout.isVisible = true
             binding.faceSetLayout.isVisible = false
+            binding.setAvatarConfirm.isVisible = false
+            binding.recapture.isVisible = false
             val saveFileName =
                 "${MainDomainData.userInfo?.userId}_avatar_${TimeUtils.nowString("yyyyMMddHHmmss")}"
             FileStorageUtils.writeText(
@@ -76,9 +98,13 @@ class UserInfoFragment : BaseFragment<FragmentUserInfoBinding>() {
             viewModel.saveUserAvatar(savePath).observe(this) {}
         }
         binding.recapture.setDebouncedClickListener {
-            isFaceChecking = false
+            reCaptureTimer.start()
+            binding.countDownTip.isVisible = false
             binding.image.isVisible = false
-            binding.preview.isVisible = true
+            binding.previewLayout.isVisible = true
+            binding.setAvatarConfirm.isVisible = false
+            binding.recapture.isVisible = false
+            binding.faceOverlayView.setFaceRect(null)
         }
         binding.confirm.setDebouncedClickListener {
             if (checkData()) {
@@ -110,7 +136,7 @@ class UserInfoFragment : BaseFragment<FragmentUserInfoBinding>() {
         binding.nicknameEt.setText(MainDomainData.userInfo?.nickName)
         binding.phoneEt.setText(MainDomainData.userInfo?.phoneNumber)
         MainDomainData.userInfo?.avatar?.let {
-            if (it.isEmpty()){
+            if (it.isEmpty()) {
                 return
             }
             if (it.file().exists()) {
@@ -133,43 +159,56 @@ class UserInfoFragment : BaseFragment<FragmentUserInfoBinding>() {
     }
 
     private fun startFace() {
-        ArcSoftUtil.inDetecting = false
-        binding.preview.isVisible = true
+        binding.previewLayout.isVisible = true
         binding.image.isVisible = false
+        ArcSoftUtil.inDetecting = false
         ArcSoftUtil.initCamera(
             requireContext(),
             requireActivity().windowManager,
-            binding.preview
+            binding.preview,
+            binding.faceOverlayView,
+            true,
         ) { bitmap, faceSize, alive ->
-            if (isFaceChecking) {
-                ArcSoftUtil.inDetecting = false
-                return@initCamera
-            }
-            isFaceChecking = true
             binding.tipTv.isVisible = faceSize > 1 || alive == false
             logger.info("人脸检测结果: ${bitmap == null},$faceSize,$alive")
             if (faceSize > 1) {
                 binding.tipTv.text = getString(R.string.only_one_person_allowed)
-                isFaceChecking = false
                 ArcSoftUtil.inDetecting = false
+                stopCountDown()
                 return@initCamera
             }
             if (alive == false) {
                 binding.tipTv.text =
                     getString(R.string.real_person_verification_required)
-                isFaceChecking = false
                 ArcSoftUtil.inDetecting = false
+                stopCountDown()
                 return@initCamera
             }
-            binding.preview.visibility = View.INVISIBLE
-            binding.image.visibility = View.VISIBLE
-            mCapturedBitmap = bitmap
-            binding.image.setImageBitmap(bitmap)
-            binding.recapture.visibility = View.VISIBLE
-            binding.confirm.visibility = View.VISIBLE
+            if (!isInCountDown) {
+                startCountDown()
+            }
+            if (!isFaceDetect) {
+                mCapturedBitmap = bitmap
+                binding.image.setImageBitmap(bitmap)
+            }
+            ArcSoftUtil.inDetecting = false
         }
     }
 
+    private fun startCountDown() {
+        isInCountDown = true
+        binding.countDownTip.text = getString(R.string.detect_face_tip)
+        binding.countDownTip.isVisible = true
+        captureTimer.start()
+    }
+
+    private fun stopCountDown() {
+        isInCountDown = false
+        binding.countDownTip.text = getString(R.string.detect_face_tip)
+        binding.countDownTip.isVisible = false
+        captureTimer.cancel()
+    }
+
     private fun releaseFace() {
         ArcSoftUtil.stop()
     }

+ 50 - 15
app/src/main/res/layout-land/fragment_user_info.xml

@@ -242,11 +242,58 @@
                         android:layout_weight="1"
                         android:background="@drawable/common_card_bg">
 
-                        <TextureView
-                            android:id="@+id/preview"
+                        <FrameLayout
+                            android:id="@+id/preview_layout"
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
-                            android:visibility="invisible" />
+                            android:visibility="visible">
+
+                            <TextureView
+                                android:id="@+id/preview"
+                                android:layout_width="match_parent"
+                                android:layout_height="match_parent" />
+
+
+                            <com.grkj.shared.widget.FaceOverlayView
+                                android:id="@+id/face_overlay_view"
+                                android:layout_width="match_parent"
+                                android:layout_height="match_parent" />
+
+                            <FrameLayout
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_gravity="bottom"
+                                android:background="@color/common_transparent_half">
+
+                                <TextView
+                                    android:id="@+id/count_down_tip"
+                                    android:layout_width="wrap_content"
+                                    android:layout_height="wrap_content"
+                                    android:layout_gravity="center"
+                                    android:gravity="center"
+                                    android:paddingVertical="@dimen/common_spacing"
+                                    android:text="@string/detect_face_tip"
+                                    android:textColor="@color/dialogxColorBlue"
+                                    android:textSize="@dimen/common_text_size_big"
+                                    android:textStyle="bold"
+                                    android:visibility="gone"
+                                    tools:text="检测到人脸,即将拍摄" />
+
+                                <TextView
+                                    android:id="@+id/tip_tv"
+                                    android:layout_width="match_parent"
+                                    android:layout_height="wrap_content"
+                                    android:layout_gravity="center|bottom"
+                                    android:gravity="center"
+                                    android:paddingVertical="10dp"
+                                    android:text="@string/only_one_person_allowed"
+                                    android:textColor="@color/common_status_red"
+                                    android:textSize="@dimen/common_text_size_big"
+                                    android:visibility="gone"
+                                    tools:text="请保证画面中只有自己" />
+                            </FrameLayout>
+
+                        </FrameLayout>
 
                         <ImageView
                             android:id="@+id/image"
@@ -293,18 +340,6 @@
                             android:textColor="@color/black"
                             android:textSize="@dimen/common_text_size_small" />
 
-                        <TextView
-                            android:id="@+id/tip_tv"
-                            android:layout_width="match_parent"
-                            android:layout_height="wrap_content"
-                            android:layout_marginTop="10dp"
-                            android:background="@color/common_status_red"
-                            android:gravity="center"
-                            android:text="@string/only_one_person_allowed"
-                            android:textColor="@color/white"
-                            android:textSize="@dimen/common_text_size_big"
-                            android:visibility="gone"
-                            tools:text="请保证画面中只有自己" />
                     </LinearLayout>
                 </LinearLayout>
 

+ 10 - 4
app/src/main/res/layout/fragment_set_fingerprint.xml

@@ -120,12 +120,18 @@
                 android:textSize="@dimen/common_text_size" />
         </LinearLayout>
 
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/list_rv"
+        <com.drake.statelayout.StateLayout
+            android:id="@+id/state"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_marginHorizontal="@dimen/common_spacing_2x"
-            android:layout_marginBottom="@dimen/common_spacing"
-            android:background="@drawable/common_card_bg" />
+            android:layout_marginBottom="@dimen/common_spacing">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/list_rv"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="@drawable/common_card_bg" />
+        </com.drake.statelayout.StateLayout>
     </LinearLayout>
 </layout>

+ 50 - 16
app/src/main/res/layout/fragment_user_info.xml

@@ -236,11 +236,58 @@
                     android:layout_weight="1"
                     android:background="@drawable/common_card_bg">
 
-                    <TextureView
-                        android:id="@+id/preview"
+                    <FrameLayout
+                        android:id="@+id/preview_layout"
                         android:layout_width="match_parent"
                         android:layout_height="match_parent"
-                        android:visibility="invisible" />
+                        android:visibility="visible">
+
+                        <TextureView
+                            android:id="@+id/preview"
+                            android:layout_width="match_parent"
+                            android:layout_height="match_parent" />
+
+                        <com.grkj.shared.widget.FaceOverlayView
+                            android:id="@+id/face_overlay_view"
+                            android:layout_width="match_parent"
+                            android:layout_height="match_parent" />
+
+                        <FrameLayout
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_gravity="bottom"
+                            android:background="@color/common_transparent_half">
+
+                            <TextView
+                                android:id="@+id/count_down_tip"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:layout_gravity="center"
+                                android:paddingVertical="@dimen/common_spacing"
+                                android:text="@string/detect_face_tip"
+                                android:gravity="center"
+                                android:textColor="@color/dialogxColorBlue"
+                                android:textSize="@dimen/common_text_size_big"
+                                android:textStyle="bold"
+                                android:visibility="gone"
+                                tools:text="检测到人脸,即将拍摄" />
+
+                            <TextView
+                                android:id="@+id/tip_tv"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:layout_gravity="center"
+                                android:layout_marginTop="10dp"
+                                android:layout_marginBottom="@dimen/common_spacing"
+                                android:gravity="center"
+                                android:paddingVertical="@dimen/common_spacing"
+                                android:text="@string/only_one_person_allowed"
+                                android:textColor="@color/common_status_red"
+                                android:textSize="@dimen/common_text_size_big"
+                                android:visibility="gone"
+                                tools:text="请保证画面中只有自己" />
+                        </FrameLayout>
+                    </FrameLayout>
 
                     <ImageView
                         android:id="@+id/image"
@@ -286,19 +333,6 @@
                         android:text="@string/capture_tip_content"
                         android:textColor="@color/black"
                         android:textSize="@dimen/common_text_size_small" />
-
-                    <TextView
-                        android:id="@+id/tip_tv"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_marginTop="10dp"
-                        android:background="@color/common_status_red"
-                        android:gravity="center"
-                        android:text="@string/only_one_person_allowed"
-                        android:textColor="@color/white"
-                        android:textSize="@dimen/common_text_size_big"
-                        android:visibility="gone"
-                        tools:text="请保证画面中只有自己" />
                 </LinearLayout>
 
                 <androidx.constraintlayout.widget.ConstraintLayout

+ 1 - 1
app/src/main/res/values-zh/strings.xml

@@ -174,7 +174,7 @@
     <string name="user_name">登录名</string>
     <string name="please_input_phone">请输入电话</string>
     <string name="phone">电话</string>
-    <string name="reset_password_title">密码重置</string>
+    <string name="reset_password_title">重置密码</string>
     <string name="old_password">旧密码</string>
     <string name="please_input_old_password">请输入旧密码</string>
     <string name="new_password">新密码</string>

+ 1 - 1
app/src/main/res/values/strings.xml

@@ -173,7 +173,7 @@
     <string name="user_name">登录名</string>
     <string name="please_input_phone">请输入电话</string>
     <string name="phone">电话</string>
-    <string name="reset_password_title">密码重置</string>
+    <string name="reset_password_title">重置密码</string>
     <string name="old_password">旧密码</string>
     <string name="please_input_old_password">请输入旧密码</string>
     <string name="new_password">新密码</string>