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

Kotlin RecyclerView滚动数据消失及日期显示错误问题求助

问题修复方案

1. RecyclerView滚动时数据消失

这种问题绝大多数是Adapter数据源维护错误或ViewHolder复用逻辑不当导致的,按以下方法修复:

(1)确保Adapter持有稳定的数据源引用

不要在onBindViewHolder里临时生成数据列表,也不要每次刷新都重新初始化集合。让Adapter持有一个全局可变集合,更新数据时直接替换内容并通知刷新:

class YourAdapter(private var dataList: MutableList<YourDataModel>) : RecyclerView.Adapter<YourViewHolder>() {
    fun updateData(newData: List<YourDataModel>) {
        dataList.run {
            clear()
            addAll(newData)
        }
        notifyDataSetChanged() // 追求效率的话可以用DiffUtil做局部刷新
    }

    override fun onBindViewHolder(holder: YourViewHolder, position: Int) {
        val item = dataList[position]
        // 所有视图都要明确赋值,不要依赖默认状态
        holder.tvTitle.text = item.title ?: ""
        holder.tvDate.text = item.formattedDate ?: ""
    }
}

(2)检查ViewHolder绑定逻辑

绝对不要只在数据非空时才赋值,否则复用ViewHolder时会保留上一次的内容。比如:

// 错误:没数据时不赋值,导致复用空白
if (item.title != null) holder.tvTitle.text = item.title

// 正确:无论是否有数据都明确赋值
holder.tvTitle.text = item.title ?: "无标题"

(3)确认布局管理器正常

优先使用系统自带的LinearLayoutManager/GridLayoutManager,避免自定义布局管理器的复用bug:

recyclerView.apply {
    layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
    adapter = yourAdapter
}

2. 日期显示提前一天

这是时区不匹配的典型问题:Google Spreadsheet的日期默认以UTC存储,本地解析时用了设备时区,导致日期偏移一天。修复方法:

(1)解析时强制处理时区

如果通过API获取的是ISO格式字符串(比如2023-01-01T00:00:00Z),用java.time类库正确转换时区:

import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.ZoneId

fun formatSheetDate(utcDateStr: String): String {
    val utcFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME.withZone(ZoneId.of("UTC"))
    val utcDateTime = ZonedDateTime.parse(utcDateStr, utcFormatter)
    // 转换为设备本地时区的日期
    val localDate = utcDateTime.withZoneSameInstant(ZoneId.systemDefault()).toLocalDate()
    return localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
}

(2)旧版Date类处理方式(如果还在使用)

import java.text.SimpleDateFormat
import java.util.TimeZone

fun formatOldDate(utcTimestamp: Long): String {
    val sdf = SimpleDateFormat("yyyy-MM-dd")
    // 先按UTC解析原始时间
    sdf.timeZone = TimeZone.getTimeZone("UTC")
    val utcDate = sdf.parse(sdf.format(utcTimestamp))
    // 再转本地时区格式化
    sdf.timeZone = TimeZone.getDefault()
    return sdf.format(utcDate)
}

(3)额外验证

检查Google表格的时区设置(文件 > 电子表格设置),确保表格时区符合预期,但即使表格时区正确,API返回的仍是UTC时间,所以解析时必须做时区转换。


补充排查

如果用了DiffUtil,务必保证areItemsTheSame和areContentsTheSame逻辑正确,否则会导致局部刷新失败;另外,更新Adapter必须在主线程执行,否则会出现数据不同步问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:52:36