You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView排序求助:基于Firebase数据按自定义字段排序

解决Firebase数据在RecyclerView中的自定义排序问题

我明白你被RecyclerView的排序问题困扰了——从Firebase拉取的数据需要按自定义字段排序,比如startTimeString升序或者totalTimeSpendAtworkString降序。核心问题在于你当前是直接遍历Firebase的DataSnapshot子节点并添加到适配器,而Firebase默认是按节点Key排序的,不会遵循你的业务字段规则。下面是具体的解决方案:

关键思路

  1. 先把所有Firebase返回的WorkTimeCountedClass对象收集到一个列表中
  2. 对列表按你需要的规则排序(注意:字符串类型的时间/时长需要转换成可比较的数值/日期对象,避免字符串排序的逻辑错误)
  3. 将排序后的列表逐个添加到GroupAdapter

修改后的完整代码

private fun fetchHours(){
    val link = FirebaseAuth.getInstance().uid ?: return // 空值安全处理
    val ref = FirebaseDatabase.getInstance().getReference("/WorkTime/$link")
    ref.addListenerForSingleValueEvent(object: ValueEventListener{
        override fun onDataChange(p0: DataSnapshot) {
            val adapter = GroupAdapter<GroupieViewHolder>()
            // 1. 先收集所有数据到列表
            val workTimeItems = mutableListOf<CounterActivity.WorkTimeCountedClass>()
            p0.children.forEach {
                Log.d("Vievactivity", it.toString())
                val singlerow = it.getValue(CounterActivity.WorkTimeCountedClass::class.java)
                singlerow?.let { item ->
                    workTimeItems.add(item)
                }
            }

            // 2. 选择你需要的排序规则(二选一,或者根据用户偏好动态切换)
            // 选项A:按startTimeString升序(假设格式为"yyyy-MM-dd HH:mm:ss",根据你的实际格式调整)
            workTimeItems.sortBy { 
                try {
                    LocalDateTime.parse(it.startTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
                } catch (e: DateTimeParseException) {
                    // 解析失败时,将该条目排到最后
                    LocalDateTime.MIN
                }
            }

            // 选项B:按totalTimeSpendAtworkString降序(假设格式为"XhYm",比如"8h30m")
            /*
            workTimeItems.sortByDescending { item ->
                // 用正则匹配小时和分钟数,处理格式不统一的情况
                val pattern = Regex("(\\d+)h?(\\d+)?m?")
                val matchResult = pattern.find(item.totalTimeSpendAtworkString)
                val hours = matchResult?.groups?.get(1)?.value?.toIntOrNull() ?: 0
                val minutes = matchResult?.groups?.get(2)?.value?.toIntOrNull() ?: 0
                hours * 60 + minutes // 转成总分钟数进行比较
            }
            */

            // 3. 将排序后的列表添加到适配器
            workTimeItems.forEach {
                adapter.add(WorkTimeList(it))
            }

            recycleViev_list.adapter = adapter
            adapter.setOnItemClickListener{ item, view -> 
                val useruuid = item as WorkTimeList
                val intent = Intent(view.context, EditDataActivity::class.java)
                intent.putExtra(CLICKED_ITEM_KEY, useruuid.naz.uuid)
                startActivity(intent)
            }
        }

        override fun onCancelled(p0: DatabaseError) {
            // 可以添加错误提示逻辑
            Log.e("FetchHours", "Failed to fetch data: ${p0.message}")
        }
    })
}

class WorkTimeList(var naz: CounterActivity.WorkTimeCountedClass): Item<GroupieViewHolder>(){
    override fun bind(viewHolder: GroupieViewHolder, position: Int) {
        viewHolder.itemView.row_viewactivity_invisible_uuid.text = naz.uuid
        viewHolder.itemView.Row_viewactivity_employer.text = naz.employer
        viewHolder.itemView.Row_viewactivity_StartWork.text = naz.startTimeString
        viewHolder.itemView.Row_viewactivity_StopWork.text = naz.stopTimeString
        viewHolder.itemView.imageView_planTime.text = naz.planedTimeToSpendAtWorkString
        viewHolder.itemView.imageView_complitedTime.text = naz.totalTimeSpendAtworkString
        viewHolder.itemView.imageView_overHours.text = naz.overHoursString
    }

    override fun getLayout(): Int {
        return R.layout.row_viewactivity
    }
}

重要注意事项

  • 日期格式匹配:如果你的startTimeString不是yyyy-MM-dd HH:mm:ss格式,一定要修改DateTimeFormatter.ofPattern()里的参数,比如MM/dd/yyyy hh:mm a对应"02/15/2024 03:30 PM"这种格式。如果API低于26,需要引入ThreeTenABP库来使用Java 8的日期类。
  • 时长格式鲁棒性:如果totalTimeSpendAtworkString存在多种格式(比如只有小时、只有分钟),正则表达式的方式比直接split更可靠,能避免解析失败。
  • 空值安全:代码中添加了link的空值判断,避免因用户未登录导致的崩溃。

内容的提问来源于stack exchange,提问作者Rico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:42:42