5 Commits
Author SHA1 Message Date
zxj 9a89fff9dd 工具类优化 2025-07-28 17:35:21 +08:00
zxj cc317117bc 修复了排序问题 2025-07-28 17:09:24 +08:00
zxj ca081f659b 初步实现功能 2025-07-28 15:47:55 +08:00
zxj 307fc70ae2 实现了垂直排序 2025-07-28 10:50:15 +08:00
zxj 8780f5d463 倒计时+1 2025-07-25 16:33:50 +08:00
10 changed files with 148 additions and 29 deletions
+11
View File
@@ -4,6 +4,17 @@
<selectionStates>
<SelectionState runConfigName="SmartPlateCabinet.app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-07-25T08:39:03.160022800Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="Default" identifier="serial=?;connection=93a2ccce" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
<SelectionState runConfigName="LoginByFaceActivity">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
@@ -15,19 +15,17 @@ object GlobalData {
/**
* 横排数量
*/
var arrayCross: Int = 3
var arrayCross: Int = 2
/**
* 竖排数量
*/
var arrayVertical: Int = 11
/**
* 排列方式 0 垂直 1 水平
*/
var arrayMode: Int = 0
}
/**
@@ -339,6 +339,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
override fun onGlobalLayout() {
Timber.d("onGlobalLayout")
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this)
// 请求权限
checkCameraPermission()
@@ -20,7 +20,7 @@ class PlateCabinetFullFragment :
fun initCountTime() {
object : CountDownTimer(totalTimeInMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
binding.tvAutoClose.text = "${(millisUntilFinished / 1000).toInt()}秒后返回主屏"
binding.tvAutoClose.text = "${(millisUntilFinished / 1000).toInt() + 1}秒后返回主屏"
}
override fun onFinish() {
@@ -55,7 +55,7 @@ class PlateOpenFragment :
fun initCountTime() {
object : CountDownTimer(totalTimeInMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
binding.tvAutoClose.text = (millisUntilFinished / 1000).toInt().toString()
binding.tvAutoClose.text = ((millisUntilFinished / 1000).toInt() + 1).toString()
}
override fun onFinish() {
@@ -1,6 +1,7 @@
package com.sw.platecabinet.fragment
import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@@ -22,10 +23,10 @@ import com.sw.platecabinet.databinding.ItemBindViewBinding
import com.sw.platecabinet.ext.formatNumber
import com.sw.platecabinet.ext.maskName
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.ListArrangementUtil
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch
import timber.log.Timber
import kotlin.math.ceil
/**
* 餐盘柜绑定的用户列表界面
@@ -42,7 +43,6 @@ class SettingListFragment :
* 垂直滚动的adapter
*/
private var itemAdapter: GenericItemAdapter<EquipmentUserInfo, ItemBindViewBinding>? = null
private val itemsPerPage = GlobalData.arrayCross * GlobalData.arrayVertical // 每行2个,每列11个,共22个
override fun registerDataChange() {
super.registerDataChange()
@@ -107,6 +107,11 @@ class SettingListFragment :
item: EquipmentUserInfo,
position: Int
) {
if (item.isPlaceholder() == true) {
this.llRoot.isVisible = false
return
}
this.llRoot.isVisible = true
this.tvNum.text = formatNumber(item.equipmentBoxCode ?: "")
if (item.isBound()) {
val date = DateTimeUtils.parseDateTime(item.updateTime)
@@ -174,38 +179,43 @@ class SettingListFragment :
}
fun updateAdapter(items: List<EquipmentUserInfo>) {
val itemsPerPage = 2 * GlobalData.arrayVertical // 每行2个,每列11个,共22个
if (GlobalData.arrayCross > 2) {
// 多recyclerview
var pages = if (items.size > itemsPerPage) {
items.chunked(itemsPerPage) {
convertToColumnFirst(it, 11)
if (GlobalData.arrayMode == 0) {
val pageList = items.chunked(itemsPerPage)
pageList.mapIndexed { index, it ->
var itemList: MutableList<EquipmentUserInfo> = it.toMutableList()
if (index == pageList.size - 1) {
// 补全剩余item
itemList = (itemList + List(itemsPerPage - itemList.size) {
EquipmentUserInfo()
}) as MutableList<EquipmentUserInfo>
}
ListArrangementUtil.convertToColumnFirst(itemList, GlobalData.arrayVertical)
}
} else {
val newItems =
ListArrangementUtil.horizontalSortPageItem(items, GlobalData.arrayCross)
newItems.chunked(itemsPerPage)
}
} else {
listOf(
// 根据条件判断是否需要重新排列
// items
convertToColumnFirst(items, 11)
items
)
}
pageAdapter?.updatePages(pages)
} else {
itemAdapter?.updateData(items)
// 单 recyclerview
var pages = items
if (GlobalData.arrayMode == 0) {
pages = ListArrangementUtil.verticalSortItem(pages)
}
itemAdapter?.updateData(pages)
}
binding.mainRecyclerView.scrollToPosition(0)
}
/**
* 重新排列数组
*/
private fun convertToColumnFirst(
original: List<EquipmentUserInfo>,
cols: Int
): List<EquipmentUserInfo> {
val rows = ceil(original.size.toDouble() / cols).toInt()
return List(original.size) { pos ->
val row = pos % rows
val col = pos / rows
val originalPos = col + row * cols
original[originalPos]
}
}
}
@@ -73,4 +73,8 @@ data class EquipmentUserInfo(
fun isOtherEquipment(): Boolean {
return GlobalData.globalEquipmentCode != equipmentCode
}
fun isPlaceholder(): Boolean {
return equipmentBoxCode == null || equipmentBoxCode == ""
}
}
@@ -2,6 +2,7 @@ package com.sw.inbound.utils
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@@ -67,7 +68,8 @@ object DateTimeUtils {
val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
format.parse(timeString)
} catch (e: Exception) {
e.printStackTrace()
// e.printStackTrace()
Timber.e(e.message)
null
}
}
@@ -0,0 +1,88 @@
package com.sw.platecabinet.utils
import com.sw.platecabinet.model.response.EquipmentUserInfo
import timber.log.Timber
import kotlin.math.ceil
/**
* 列表排序工具类
*/
object ListArrangementUtil {
/**
* page item水平排序
*/
fun horizontalSortPageItem(
list: List<EquipmentUserInfo>,
columns: Int,
defaultValue: EquipmentUserInfo = EquipmentUserInfo()
): List<EquipmentUserInfo> {
Timber.d("horizontalSortPageItem")
require(columns > 0) { "Columns must be positive" }
val filledList = list.padToMultiple(columns, defaultValue)
val chunks = filledList.chunked(columns)
return (0 until columns)
.windowed(2, 2, partialWindows = true)
.flatMap { group ->
when (group.size) {
2 -> chunks.flatMap { listOf(it[group[0]], it[group[1]]) }
1 -> chunks.flatMap {
listOf(it[group[0]], EquipmentUserInfo(equipmentBoxCode = null))
}.dropLast(1)
else -> error("Unexpected group size")
}
}
}
/**
* item 垂直排序
*/
fun verticalSortItem(list: List<EquipmentUserInfo>): List<EquipmentUserInfo> {
Timber.d("verticalSortItem")
val users = list.padToEvenSize()
val half = users.size / 2
return users.take(half)
.zip(users.drop(half)) { a, b -> listOf(a, b) }
.flatten()
}
/**
* page item垂直排序
*/
fun convertToColumnFirst(
original: List<EquipmentUserInfo>,
cols: Int
): List<EquipmentUserInfo> {
Timber.d("convertToColumnFirst")
require(cols > 0) { "Columns must be positive" }
val rows = ceil(original.size.toDouble() / cols).toInt()
return List(original.size) { pos ->
original.getOrNull(pos % rows * cols + pos / rows) ?: EquipmentUserInfo()
}
}
// 提取的扩展函数
private fun List<EquipmentUserInfo>.padToMultiple(
multiple: Int,
defaultValue: EquipmentUserInfo
): List<EquipmentUserInfo> {
return if (size % multiple != 0) {
this + List(multiple - (size % multiple)) { defaultValue }
} else {
this
}
}
private fun List<EquipmentUserInfo>.padToEvenSize(): List<EquipmentUserInfo> {
return if (size % 2 != 0) {
Timber.d("列表长度必须是偶数")
this + EquipmentUserInfo()
} else {
this
}
}
}
@@ -46,6 +46,11 @@ class SettingViewModel : BaseViewModel() {
_equipmentList.value = response.data ?: emptyList()
}
}
// val list = mutableListOf<EquipmentUserInfo>()
// for (i in 1 .. 30){
// list.add(EquipmentUserInfo(id = i, equipmentBoxCode = i.toString()))
// }
// _equipmentList.value = list
}
/**