From d06bf11b9507120b9f3db0180a029ea46bf35c56 Mon Sep 17 00:00:00 2001 From: dongliang Date: Mon, 27 Apr 2026 16:46:59 +0930 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=91=E5=AE=9A=E9=A1=B5UI=E5=AF=B9?= =?UTF-8?q?=E9=BD=90=E5=8E=9F=E5=9E=8B=E5=9B=BEV3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 二维码页面:标题移到上方,白色圆角背景框,说明文字居中 - 新增配对中Loading状态(spinner + "正在配对…") - 颜色值对齐原型图(blue=#3B9EFF, green=#4ADE80, orange=#FFB340, red=#FF6B6B) - 新增 bg_qr_frame.xml 白色圆角背景 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../com/xiaoqu/watch/ui/bind/BindFragment.kt | 59 +++++---- app/src/main/res/drawable/bg_qr_frame.xml | 7 ++ app/src/main/res/layout/fragment_bind.xml | 112 ++++++++++++------ app/src/main/res/values/colors.xml | 14 +-- 4 files changed, 126 insertions(+), 66 deletions(-) create mode 100644 app/src/main/res/drawable/bg_qr_frame.xml diff --git a/app/src/main/java/com/xiaoqu/watch/ui/bind/BindFragment.kt b/app/src/main/java/com/xiaoqu/watch/ui/bind/BindFragment.kt index 0e3055f..db5a850 100644 --- a/app/src/main/java/com/xiaoqu/watch/ui/bind/BindFragment.kt +++ b/app/src/main/java/com/xiaoqu/watch/ui/bind/BindFragment.kt @@ -1,5 +1,6 @@ package com.xiaoqu.watch.ui.bind +import android.graphics.Bitmap import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,7 +11,6 @@ import com.google.gson.Gson import com.google.zxing.BarcodeFormat import com.google.zxing.MultiFormatWriter import com.google.zxing.common.BitMatrix -import android.graphics.Bitmap import com.xiaoqu.watch.R import com.xiaoqu.watch.data.device.WatchBindInfo import com.xiaoqu.watch.data.prefs.DevicePrefs @@ -28,8 +28,9 @@ import javax.inject.Inject /** * 设备绑定页面 - * 显示二维码供手机 APP 扫码绑定 - * 监听 MQTT messageType=2 绑定成功消息 + * 两种状态: + * 1. 二维码展示 — 等待手机 APP 扫码 + * 2. 配对中 — 收到 MQTT 绑定消息后,显示 Loading,API 确认后跳转首页 */ @AndroidEntryPoint class BindFragment : BaseFragment() { @@ -57,10 +58,10 @@ class BindFragment : BaseFragment() { /** * 生成二维码 * 编码设备信息 JSON:{bluetoothName, imei, serial, power} + * 与旧版 codeScanPair.vue 格式一致 */ private fun generateQrCode() { try { - // 构建设备信息 JSON(与旧版 codeScanPair.vue 一致) val qrData = gson.toJson(mapOf( "bluetoothName" to devicePrefs.bluetoothName, "imei" to devicePrefs.imei, @@ -69,8 +70,8 @@ class BindFragment : BaseFragment() { )) Timber.d("绑定: QR 数据=$qrData") - // 使用 ZXing 生成二维码 Bitmap - val size = 500 // 生成 500×500 像素,ImageView 会缩放 + // ZXing 生成二维码 Bitmap + val size = 500 val bitMatrix: BitMatrix = MultiFormatWriter().encode( qrData, BarcodeFormat.QR_CODE, size, size ) @@ -82,10 +83,7 @@ class BindFragment : BaseFragment() { } } - /** - * 将 ZXing BitMatrix 转换为 Android Bitmap - * 黑色像素用黑色,白色像素用白色 - */ + /** 将 ZXing BitMatrix 转换为 Android Bitmap */ private fun bitMatrixToBitmap(matrix: BitMatrix): Bitmap { val width = matrix.width val height = matrix.height @@ -93,9 +91,9 @@ class BindFragment : BaseFragment() { for (y in 0 until height) { for (x in 0 until width) { pixels[y * width + x] = if (matrix[x, y]) { - 0xFF000000.toInt() // 黑色 + 0xFF000000.toInt() // 黑色模块 } else { - 0xFFFFFFFF.toInt() // 白色 + 0xFFFFFFFF.toInt() // 白色背景 } } } @@ -104,7 +102,7 @@ class BindFragment : BaseFragment() { /** * 监听 MQTT 绑定成功消息(messageType=2) - * 收到后存储用户信息 → 调用 API 确认 → 导航到首页 + * 收到后切换到配对中状态 → 存储用户信息 → API 确认 → 导航到首页 */ private fun observeBindEvent() { viewLifecycleOwner.lifecycleScope.launch { @@ -118,14 +116,18 @@ class BindFragment : BaseFragment() { /** * 处理绑定成功 - * 1. 解析用户信息并存入 UserPrefs - * 2. 调用 bindWatchConfirm API 确认 - * 3. 导航到首页 + * 1. 切换到配对中 Loading 状态 + * 2. 解析用户信息并存入 UserPrefs + * 3. 调用 bindWatchConfirm API 确认 + * 4. 导航到首页 */ private fun handleBindSuccess(rawJson: String) { try { Timber.d("绑定: 收到绑定消息 $rawJson") + // 切换到配对中状态 + showLoading() + // 解析用户信息 val bindInfo = gson.fromJson(rawJson, WatchBindInfo::class.java) @@ -137,22 +139,35 @@ class BindFragment : BaseFragment() { headUrl = bindInfo.headUrl ) - // 调用 API 确认绑定 + // 调用 API 确认绑定,然后导航到首页 viewLifecycleOwner.lifecycleScope.launch { val params = mapOf( "imei" to devicePrefs.imei, "userId" to bindInfo.userId ) safeApiCall { commonApi.bindWatchConfirm(params) } - Timber.d("绑定: 确认 API 已调用") - } + Timber.d("绑定: 确认 API 已调用,导航到首页") - // 导航到首页 - Timber.d("绑定: 绑定成功,导航到首页") - findNavController().navigate(R.id.action_bind_to_home) + // 导航到首页 + findNavController().navigate(R.id.action_bind_to_home) + } } catch (e: Exception) { Timber.e(e, "绑定: 处理绑定消息异常") + // 异常时恢复二维码显示 + showQrCode() } } + + /** 显示二维码状态 */ + private fun showQrCode() { + binding.qrWrap.visibility = View.VISIBLE + binding.loadingWrap.visibility = View.GONE + } + + /** 显示配对中 Loading 状态 */ + private fun showLoading() { + binding.qrWrap.visibility = View.GONE + binding.loadingWrap.visibility = View.VISIBLE + } } diff --git a/app/src/main/res/drawable/bg_qr_frame.xml b/app/src/main/res/drawable/bg_qr_frame.xml new file mode 100644 index 0000000..6485497 --- /dev/null +++ b/app/src/main/res/drawable/bg_qr_frame.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/layout/fragment_bind.xml b/app/src/main/res/layout/fragment_bind.xml index 46d4f5b..30c93f8 100644 --- a/app/src/main/res/layout/fragment_bind.xml +++ b/app/src/main/res/layout/fragment_bind.xml @@ -1,45 +1,83 @@ - - + + android:background="@color/background"> - - + + - - + + - - + + - + + - + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7cf48d4..bbf017f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -6,14 +6,14 @@ #FF000000 - - #FF007AFF - #FF339AFB + + #FF3B9EFF + #FF3B9EFF - - #FF1CC46B - #FFEB9A26 - #FFDA5050 + + #FF4ADE80 + #FFFFB340 + #FFFF6B6B #FF666666