Kotlin 基于Calendar添加本地日期时间过滤器实现列表筛选
问题定位
筛选逻辑失效、页面始终展示全量月度数据的核心原因有两个:
- 日历组件返回的
Calendar实例时间范围未和PM工单实体的时间字段做统一精度、统一时区的范围比对 - 时间选择完成后未将过滤后的结果替换为适配器数据源,也未触发列表刷新,始终展示初始化加载的全量月度缓存数据
修复代码(所有原有类名、方法名、变量名保持不变)
1. 补充本地范围过滤方法
在原有页面/ViewModel的筛选逻辑同级位置新增过滤方法,全程复用原有已定义的变量、实体字段:
/** * 按选择的时间范围过滤PM工单列表 * @param originalList 页面初始化加载的全量月度PM工单缓存列表,禁止直接修改该数据源 * @param startTimeCal 日历组件返回的起始时间Calendar实例 * @param endTimeCal 日历组件返回的结束时间Calendar实例 */ private fun filterPmWorkOrderByTimeRange( originalList: List<PmWorkOrder>, startTimeCal: Calendar, endTimeCal: Calendar ): List<PmWorkOrder> { // 统一转毫秒级时间戳,对齐时间精度 val rangeStart = startTimeCal.timeInMillis // 补全结束时间为当日23:59:59.999,避免结束当日的工单数据被遗漏 endTimeCal.apply { set(Calendar.HOUR_OF_DAY, 23) set(Calendar.MINUTE, 59) set(Calendar.SECOND, 59) set(Calendar.MILLISECOND, 999) } val rangeEnd = endTimeCal.timeInMillis return originalList.filter { order -> // 此处直接复用原有工单实体的时间字段(如createTime、reportTime等),不要修改字段名 // 若字段为字符串格式,先用项目原有时间格式化工具转为Long类型时间戳再比对 val orderTimestamp = order.createTime orderTimestamp in rangeStart..rangeEnd } }
2. 替换日历选择回调逻辑
将原有日历组件选择完成后的回调替换为以下逻辑,确保筛选结果正确刷新到UI:
// 保持原有回调方法名、参数定义不变 override fun onDateRangeSelected(startCalendar: Calendar, endCalendar: Calendar) { // 基于全量缓存列表做过滤,禁止使用当前适配器展示的列表做二次过滤,避免结果异常 val filteredResult = filterPmWorkOrderByTimeRange( originalList = mAllMonthPmWorkOrderList, startTimeCal = startCalendar, endTimeCal = endCalendar ) // 复用原有列表适配器实例更新数据 mPmWorkOrderAdapter.apply { data.clear() data.addAll(filteredResult) notifyDataSetChanged() } // 复用原有空态控制逻辑 if (filteredResult.isEmpty()) showEmptyView() else hideEmptyView() }
避坑说明
- 所有筛选操作必须基于首次加载月份数据时缓存的全量列表
mAllMonthPmWorkOrderList执行,不要修改该缓存列表的内容,否则重置筛选、切换月份时会出现数据丢失 - 若工单时间字段为字符串格式,必须使用项目内统一的时间转换工具转为Long时间戳后再做范围比对,禁止直接比对日期字符串
- 月份切换时,需要先更新全量缓存列表为新月份的全量数据,再重新执行筛选逻辑,避免跨月筛选结果异常
- 重置筛选时,直接将全量缓存列表重新设置给适配器并刷新即可恢复全量月度数据展示
内容的提问来源于stack exchange,提问作者yata srivaishnavi
相关产品推荐
相关产品推荐

