Browse Source

修改添加主板逻辑,设备状态页将钥匙和挂锁显示在同一个列表,保留空行显示

Frankensteinly 6 tháng trước cách đây
mục cha
commit
1863d70802

+ 1 - 1
app/build.gradle

@@ -122,6 +122,6 @@ dependencies {
     implementation "androidx.camera:camera-lifecycle:1.2.0"
     implementation "androidx.camera:camera-view:1.2.0"
 
-    // ML Kit 面部检测库
+    // ML Kit 面部检测库(备份,已改用虹软以补充活体检测)
     implementation 'com.google.mlkit:face-detection:16.1.5'
 }

+ 94 - 62
app/src/main/java/com/grkj/iscs/view/fragment/DeviceStatusFragment.kt

@@ -1,101 +1,133 @@
 package com.grkj.iscs.view.fragment
 
+import android.content.Context
+import androidx.recyclerview.widget.RecyclerView
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.FragmentDeviceStatusBinding
 import com.grkj.iscs.extentions.setSelected
 import com.grkj.iscs.extentions.setVisibleWithHolder
 import com.grkj.iscs.modbus.ModBusController
+import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_KEY
+import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_LOCK
 import com.grkj.iscs.view.base.BaseMvpFragment
 import com.grkj.iscs.view.fragment.DockTestFragment.DockTestBean
 import com.grkj.iscs.view.iview.IDeviceStatusView
 import com.grkj.iscs.view.presenter.DeviceStatusPresenter
 import com.zhy.adapter.recyclerview.CommonAdapter
+import com.zhy.adapter.recyclerview.MultiItemTypeAdapter
+import com.zhy.adapter.recyclerview.base.ItemViewDelegate
 import com.zhy.adapter.recyclerview.base.ViewHolder
 
 /**
  * 设备状态页
  */
 class DeviceStatusFragment : BaseMvpFragment<IDeviceStatusView, DeviceStatusPresenter, FragmentDeviceStatusBinding>() {
-    private var mRowKeyList = mutableListOf<KeyDockStatusBO>()
-    private var mRowLockList = mutableListOf<LockDockStatusBO>()
+    private var mRowList = mutableListOf<DockStatusBO>()
 
     override val viewBinding: FragmentDeviceStatusBinding
         get() = FragmentDeviceStatusBinding.inflate(layoutInflater)
 
     override fun initView() {
-        presenter?.initData(mRowKeyList, mRowLockList)
-
-        mBinding?.rvKey?.adapter = object :
-            CommonAdapter<KeyDockStatusBO>(requireActivity(), R.layout.item_rv_key_dock_status, mRowKeyList) {
-            override fun convert(holder: ViewHolder, row: KeyDockStatusBO, position: Int) {
-                holder.setVisibleWithHolder(R.id.ll_left, row.dockList.any { it.column == "1" })
-                holder.setVisibleWithHolder(R.id.ll_right, row.dockList.any { it.column == "2" })
-                holder.setSelected(R.id.iv_key_1, ModBusController.isKeyExist(row.dockList.find { it.column == "1" }?.address, true))
-                holder.setSelected(R.id.iv_key_2, ModBusController.isKeyExist(row.dockList.find { it.column == "1" }?.address, false))
-                holder.setSelected(R.id.iv_key_3, ModBusController.isKeyExist(row.dockList.find { it.column == "2" }?.address, true))
-                holder.setSelected(R.id.iv_key_4, ModBusController.isKeyExist(row.dockList.find { it.column == "2" }?.address, false))
-                val status1 = presenter?.getKeyStatus(row.dockList.find { it.column == "1" }?.address, true)
-                val status2 = presenter?.getKeyStatus(row.dockList.find { it.column == "1" }?.address, false)
-                val status3 = presenter?.getKeyStatus(row.dockList.find { it.column == "2" }?.address, true)
-                val status4 = presenter?.getKeyStatus(row.dockList.find { it.column == "2" }?.address, false)
-                holder.setSelected(R.id.rl_status_1, status1?.first == true)
-                holder.setSelected(R.id.rl_status_2, status2?.first == true)
-                holder.setSelected(R.id.rl_status_3, status3?.first == true)
-                holder.setSelected(R.id.rl_status_4, status4?.first == true)
-                holder.setText(R.id.tv_status_1, status1?.second)
-                holder.setText(R.id.tv_status_2, status2?.second)
-                holder.setText(R.id.tv_status_3, status3?.second)
-                holder.setText(R.id.tv_status_4, status4?.second)
-                holder.setVisibleWithHolder(R.id.tv_repair_1, status1?.first == false)
-                holder.setVisibleWithHolder(R.id.tv_repair_2, status2?.first == false)
-                holder.setVisibleWithHolder(R.id.tv_repair_3, status3?.first == false)
-                holder.setVisibleWithHolder(R.id.tv_repair_4, status4?.first == false)
-                holder.setOnClickListener(R.id.tv_repair_1) {
-                    presenter?.repairKey(row.dockList.find { it.column == "1" }?.address, true)
-                }
-                holder.setOnClickListener(R.id.tv_repair_2) {
-                    presenter?.repairKey(row.dockList.find { it.column == "1" }?.address, false)
-                }
-                holder.setOnClickListener(R.id.tv_repair_3) {
-                    presenter?.repairKey(row.dockList.find { it.column == "2" }?.address, true)
-                }
-                holder.setOnClickListener(R.id.tv_repair_4) {
-                    presenter?.repairKey(row.dockList.find { it.column == "2" }?.address, false)
-                }
-            }
-        }
+        presenter?.initData(mRowList)
 
-        mBinding?.rvLock?.adapter = object :
-            CommonAdapter<LockDockStatusBO>(requireActivity(), R.layout.item_rv_lock_dock_status, mRowLockList) {
-                override fun convert(holder: ViewHolder, row: LockDockStatusBO, position: Int) {
-                    val rv = holder.getView<androidx.recyclerview.widget.RecyclerView>(R.id.rv_root)
-                    rv.adapter = object :
-                        CommonAdapter<Int>(requireActivity(), R.layout.item_rv_lock_dock_child_status, row.dock.deviceList) {
-                            override fun convert(holder: ViewHolder, lockIdx: Int, position: Int) {
-                                holder.setSelected(R.id.root, ModBusController.isLockExist(row.dock.address, lockIdx))
-                            }
-                    }
-                }
-            }
+        val adapter = MultiItemTypeAdapter(requireContext(), mRowList)
+        adapter.addItemViewDelegate(KeyDockItemDelegate(presenter))
+        adapter.addItemViewDelegate(LockDockItemDelegate(presenter, requireContext()))
+        adapter.addItemViewDelegate(EmptyItemDelegate())
+        mBinding?.rvDock?.adapter = adapter
     }
 
     override fun onResume() {
         super.onResume()
-        mBinding?.rvKey?.adapter?.notifyDataSetChanged()
-        mBinding?.rvLock?.adapter?.notifyDataSetChanged()
+        mBinding?.rvDock?.adapter?.notifyDataSetChanged()
     }
 
     override fun initPresenter(): DeviceStatusPresenter {
         return DeviceStatusPresenter()
     }
 
-    data class KeyDockStatusBO(
+    data class DockStatusBO(
         val row: Int,
         val dockList: MutableList<DockTestBean>
     )
 
-    data class LockDockStatusBO(
-        val row: Int,
-        var dock: DockTestBean
-    )
+    class KeyDockItemDelegate(var presenter: DeviceStatusPresenter?): ItemViewDelegate<DockStatusBO> {
+        override fun getItemViewLayoutId(): Int {
+            return R.layout.item_rv_key_dock_status
+        }
+
+        override fun convert(holder: ViewHolder?, row: DockStatusBO, position: Int) {
+            holder?.setVisibleWithHolder(R.id.ll_left, row.dockList.any { it.column == "1" })
+            holder?.setVisibleWithHolder(R.id.ll_right, row.dockList.any { it.column == "2" })
+            holder?.setSelected(R.id.iv_key_1, ModBusController.isKeyExist(row.dockList.find { it.column == "1" }?.address, true))
+            holder?.setSelected(R.id.iv_key_2, ModBusController.isKeyExist(row.dockList.find { it.column == "1" }?.address, false))
+            holder?.setSelected(R.id.iv_key_3, ModBusController.isKeyExist(row.dockList.find { it.column == "2" }?.address, true))
+            holder?.setSelected(R.id.iv_key_4, ModBusController.isKeyExist(row.dockList.find { it.column == "2" }?.address, false))
+            val status1 = presenter?.getKeyStatus(row.dockList.find { it.column == "1" }?.address, true)
+            val status2 = presenter?.getKeyStatus(row.dockList.find { it.column == "1" }?.address, false)
+            val status3 = presenter?.getKeyStatus(row.dockList.find { it.column == "2" }?.address, true)
+            val status4 = presenter?.getKeyStatus(row.dockList.find { it.column == "2" }?.address, false)
+            holder?.setSelected(R.id.rl_status_1, status1?.first == true)
+            holder?.setSelected(R.id.rl_status_2, status2?.first == true)
+            holder?.setSelected(R.id.rl_status_3, status3?.first == true)
+            holder?.setSelected(R.id.rl_status_4, status4?.first == true)
+            holder?.setText(R.id.tv_status_1, status1?.second)
+            holder?.setText(R.id.tv_status_2, status2?.second)
+            holder?.setText(R.id.tv_status_3, status3?.second)
+            holder?.setText(R.id.tv_status_4, status4?.second)
+            holder?.setVisibleWithHolder(R.id.tv_repair_1, status1?.first == false)
+            holder?.setVisibleWithHolder(R.id.tv_repair_2, status2?.first == false)
+            holder?.setVisibleWithHolder(R.id.tv_repair_3, status3?.first == false)
+            holder?.setVisibleWithHolder(R.id.tv_repair_4, status4?.first == false)
+            holder?.setOnClickListener(R.id.tv_repair_1) {
+                presenter?.repairKey(row.dockList.find { it.column == "1" }?.address, true)
+            }
+            holder?.setOnClickListener(R.id.tv_repair_2) {
+                presenter?.repairKey(row.dockList.find { it.column == "1" }?.address, false)
+            }
+            holder?.setOnClickListener(R.id.tv_repair_3) {
+                presenter?.repairKey(row.dockList.find { it.column == "2" }?.address, true)
+            }
+            holder?.setOnClickListener(R.id.tv_repair_4) {
+                presenter?.repairKey(row.dockList.find { it.column == "2" }?.address, false)
+            }
+        }
+
+        override fun isForViewType(item: DockStatusBO?, position: Int): Boolean {
+            return item?.dockList?.any { it.type == DOCK_TYPE_KEY } == true
+        }
+    }
+
+    class LockDockItemDelegate(var presenter: DeviceStatusPresenter?, var ctx: Context): ItemViewDelegate<DockStatusBO> {
+        override fun getItemViewLayoutId(): Int {
+            return R.layout.item_rv_lock_dock_status
+        }
+
+        override fun convert(holder: ViewHolder?, row: DockStatusBO, position: Int) {
+            val rv = holder?.getView<RecyclerView>(R.id.rv_root)
+            rv?.adapter = object :
+                CommonAdapter<Int>(ctx, R.layout.item_rv_lock_dock_child_status, row.dockList[0].deviceList) {
+                override fun convert(holder: ViewHolder?, lockIdx: Int, position: Int) {
+                    holder?.setSelected(R.id.root, ModBusController.isLockExist(row.dockList[0].address, lockIdx))
+                }
+            }
+        }
+
+        override fun isForViewType(item: DockStatusBO?, position: Int): Boolean {
+            return item?.dockList?.any { it.type == DOCK_TYPE_LOCK } == true
+        }
+    }
+
+    class EmptyItemDelegate: ItemViewDelegate<DockStatusBO> {
+        override fun getItemViewLayoutId(): Int {
+            return R.layout.item_rv_empty_dock_status
+        }
+
+        override fun convert(holder: ViewHolder?, row: DockStatusBO, position: Int) {
+        }
+
+        override fun isForViewType(item: DockStatusBO?, position: Int): Boolean {
+            return item?.dockList?.isEmpty() == true
+        }
+    }
 }

+ 15 - 19
app/src/main/java/com/grkj/iscs/view/presenter/DeviceStatusPresenter.kt

@@ -9,7 +9,6 @@ import com.grkj.iscs.R
 import com.grkj.iscs.extentions.removeLeadingZeros
 import com.grkj.iscs.extentions.toHexStrings
 import com.grkj.iscs.modbus.ModBusController
-import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_KEY
 import com.grkj.iscs.model.DeviceConst.DOCK_TYPE_LOCK
 import com.grkj.iscs.util.Executor
 import com.grkj.iscs.util.NetApi
@@ -17,43 +16,40 @@ import com.grkj.iscs.util.SPUtils
 import com.grkj.iscs.util.ToastUtils
 import com.grkj.iscs.util.log.LogUtil
 import com.grkj.iscs.view.base.BasePresenter
-import com.grkj.iscs.view.fragment.DeviceStatusFragment.KeyDockStatusBO
-import com.grkj.iscs.view.fragment.DeviceStatusFragment.LockDockStatusBO
+import com.grkj.iscs.view.fragment.DeviceStatusFragment.DockStatusBO
 import com.grkj.iscs.view.fragment.DockTestFragment.DockTestBean
 import com.grkj.iscs.view.iview.IDeviceStatusView
 
 class DeviceStatusPresenter : BasePresenter<IDeviceStatusView>() {
 
-    fun initData(rowKeyList: MutableList<KeyDockStatusBO>, rowLockList: MutableList<LockDockStatusBO>) {
+    fun initData(rowList: MutableList<DockStatusBO>) {
         val dockConfigJson = SPUtils.getDockConfig(mContext!!)
         if (!dockConfigJson.isNullOrEmpty()) {
             val tempList: MutableList<DockTestBean> =
                 Gson().fromJson(dockConfigJson, object : TypeToken<MutableList<DockTestBean>>() {}.type)
             if (tempList.isNotEmpty()) {
-                tempList.filter { it.type == DOCK_TYPE_KEY }.forEach { dock ->
+                tempList.forEach { dock ->
                     try {
-                        rowKeyList.find { it.row == dock.row.toInt() }?.let {
+                        if (dock.type == DOCK_TYPE_LOCK) {
+                            dock.deviceList = mutableListOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+                        }
+                        rowList.find { it.row == dock.row.toInt() }?.let {
                             it.dockList.add(dock)
                         } ?: let {
-                            rowKeyList.add(KeyDockStatusBO(dock.row.toInt(), mutableListOf(dock)))
+                            rowList.add(DockStatusBO(dock.row.toInt(), mutableListOf(dock)))
                         }
                     } catch (e: Exception) {
-                        LogUtil.e("Device key status data error : ${e.message}")
+                        LogUtil.e("Device status data error : ${e.message}")
                     }
                 }
-                tempList.filter { it.type == DOCK_TYPE_LOCK }.forEach { dock ->
-                    try {
-                        dock.deviceList = mutableListOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
-                        rowLockList.find { it.row == dock.row.toInt() }?.let {
-                            it.dock = dock
-                        } ?: let {
-                            rowLockList.add(LockDockStatusBO(dock.row.toInt(), dock))
-                        }
-                    } catch (e: Exception) {
-                        LogUtil.e("Device lock status data error : ${e.message}")
+                // 添加空行
+                val maxRow = rowList.maxBy { it.row }.row
+                for (i in 1..maxRow) {
+                    if (rowList.find { it.row == i } == null) {
+                        rowList.add(DockStatusBO(i, mutableListOf()))
                     }
                 }
-                rowLockList.sortBy { it.row }
+                rowList.sortBy { it.row }
             }
         }
     }

+ 12 - 3
app/src/main/java/com/grkj/iscs/view/presenter/SystemSettingPresenter.kt

@@ -80,9 +80,18 @@ class SystemSettingPresenter : BasePresenter<ISystemSettingView>() {
                 return
             }
         }
-        if (dockList.any { it.row == row && it.column == column && it.type == type }) {
-            ToastUtils.tip(R.string.row_and_column_conflict)
-            return
+        if (dockList.any { it.row == row }) {
+            if (type == DOCK_TYPE_KEY) {
+                if (dockList.any { it.row == row && it.column == column && it.type == type }) {
+                    ToastUtils.tip(R.string.row_and_column_conflict)
+                    return
+                }
+            } else if (type == DOCK_TYPE_LOCK) {
+                if (dockList.any { it.row == row }) {
+                    ToastUtils.tip(R.string.row_conflict)
+                    return
+                }
+            }
         }
         if (!CommonUtils.isValidHex(address)) {
             ToastUtils.tip(R.string.please_input_valid_address)

+ 7 - 22
app/src/main/res/layout/fragment_device_status.xml

@@ -1,28 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:background="@drawable/item_rv_technology_sop_bg_normal"
+    android:padding="@dimen/common_spacing"
     tools:context=".view.fragment.DeviceStatusFragment">
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@drawable/item_rv_technology_sop_bg_normal"
-        android:orientation="vertical"
-        android:padding="@dimen/common_spacing">
-
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/rv_key"
-            style="@style/CommonRecyclerView"
-            android:layout_height="wrap_content" />
-
-        <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/rv_lock"
-            style="@style/CommonRecyclerView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginTop="@dimen/common_spacing" />
-    </LinearLayout>
-</androidx.core.widget.NestedScrollView>
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rv_dock"
+        style="@style/CommonRecyclerView" />
+</RelativeLayout>

+ 9 - 0
app/src/main/res/layout/item_rv_empty_dock_status.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="90dp"
+    android:layout_marginHorizontal="@dimen/common_spacing_small"
+    android:layout_marginVertical="@dimen/common_spacing_smallest"
+    android:background="@color/white" />

+ 2 - 1
app/src/main/res/layout/item_rv_key_dock_status.xml

@@ -3,7 +3,8 @@
     android:id="@+id/root"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_margin="@dimen/common_spacing_small"
+    android:layout_marginHorizontal="@dimen/common_spacing_small"
+    android:layout_marginVertical="@dimen/common_spacing_smallest"
     android:background="@color/white"
     android:orientation="horizontal"
     android:padding="@dimen/common_spacing_small">

+ 2 - 2
app/src/main/res/layout/item_rv_lock_dock_child_status.xml

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/root"
-    android:layout_width="33dp"
-    android:layout_height="100dp"
+    android:layout_width="30dp"
+    android:layout_height="90dp"
     android:layout_marginHorizontal="@dimen/common_spacing_small"
     android:background="@drawable/dock_lock_selector"
     android:orientation="horizontal" />

+ 16 - 4
app/src/main/res/layout/item_rv_lock_dock_status.xml

@@ -1,6 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/rv_root"
-    style="@style/CommonRecyclerView"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal" />
+    android:layout_marginHorizontal="@dimen/common_spacing_small"
+    android:layout_marginVertical="@dimen/common_spacing_smallest"
+    android:background="@color/white"
+    android:paddingHorizontal="@dimen/common_spacing_small">
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rv_root"
+        style="@style/CommonRecyclerView"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:orientation="horizontal" />
+</RelativeLayout>

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

@@ -292,6 +292,7 @@
     <string name="please_input_column">Please enter key column number</string>
     <string name="row_and_column_conflict">Duplicate row/column for same board type, please re-enter</string>
     <string name="column_must_be_1_or_2">Key column must be 1 or 2</string>
+    <string name="row_conflict">Row conflics</string>
     <string name="device_status">Device Status</string>
     <string name="key_does_not_exists">Key does not exist</string>
     <string name="key_no_rfid">Key RFID missing</string>

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

@@ -292,6 +292,7 @@
     <string name="please_input_column">请输入钥匙列号</string>
     <string name="row_and_column_conflict">存在相同的行列号的同类型主板,请重新输入</string>
     <string name="column_must_be_1_or_2">钥匙列号只能输入1或者2</string>
+    <string name="row_conflict">行号冲突</string>
     <string name="device_status">设备状态</string>
     <string name="key_does_not_exists">钥匙不存在</string>
     <string name="key_no_rfid">钥匙RFID缺失</string>

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

@@ -292,6 +292,7 @@
     <string name="please_input_column">请输入钥匙列号</string>
     <string name="row_and_column_conflict">存在相同的行列号的同类型主板,请重新输入</string>
     <string name="column_must_be_1_or_2">钥匙列号只能输入1或者2</string>
+    <string name="row_conflict">行号冲突</string>
     <string name="device_status">设备状态</string>
     <string name="key_does_not_exists">钥匙不存在</string>
     <string name="key_no_rfid">钥匙RFID缺失</string>