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

在RecyclerView聊天列表中添加日期标签并实现类似WhatsApp的按日期排序功能

实现WhatsApp式聊天日期分隔与排序方案

1. 新增工具函数

首先添加工具方法判断两条消息是否属于同一天,可根据项目最低兼容版本选择实现:

// 方式1:兼容低版本Android,用Calendar实现,返回当天零点的时间戳
fun getStartOfDay(timestamp: Long): Long {
    val calendar = Calendar.getInstance()
    calendar.timeInMillis = timestamp
    calendar.set(Calendar.HOUR_OF_DAY, 0)
    calendar.set(Calendar.MINUTE, 0)
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)
    return calendar.timeInMillis
}

// 你已有的日期格式化方法示例,可根据需求调整格式
fun getDate(timestamp: Long): String {
    val sdf = SimpleDateFormat("dd MMM, yyyy", Locale.getDefault())
    return sdf.format(Date(timestamp))
}

2. 预处理消息列表

在把列表传给Adapter之前,先完成排序+插入日期分隔项的操作:

fun processChatList(rawList: List<ChatTempModel>): ArrayList<ChatTempModel> {
    // 第一步:先按消息时间升序排序(旧消息在前,新消息在后,符合聊天列表展示逻辑)
    val sortedList = rawList.sortedBy { it.date }
    val processedList = arrayListOf<ChatTempModel>()

    sortedList.forEachIndexed { index, chatModel ->
        // 第一条消息前面必须加日期分隔
        if (index == 0) {
            processedList.add(
                ChatTempModel(
                    viewType = ChatAdapter.VIEW_TYPE_DATE,
                    senderName = "",
                    date = getStartOfDay(chatModel.date),
                    message = "",
                    clinicalList = null
                )
            )
        } else {
            // 和上一条消息对比是否是同一天,不是的话先加日期分隔
            val lastChat = sortedList[index-1]
            if (getStartOfDay(chatModel.date) != getStartOfDay(lastChat.date)) {
                processedList.add(
                    ChatTempModel(
                        viewType = ChatAdapter.VIEW_TYPE_DATE,
                        senderName = "",
                        date = getStartOfDay(chatModel.date),
                        message = "",
                        clinicalList = null
                    )
                )
            }
        }
        // 加入当前消息
        processedList.add(chatModel)
    }
    return processedList
}

3. 完善ChatAdapter逻辑

3.1 重写getItemViewType方法

你当前的Adapter没有重写该方法,需要添加:

override fun getItemViewType(position: Int): Int {
    return list[position].viewType
}

3.2 添加数据更新方法(可选,推荐)

方便后续更新列表,避免每次重新初始化Adapter:

fun updateList(newList: ArrayList<ChatTempModel>) {
    this.list = newList
    notifyDataSetChanged()
    // 性能要求高可以替换为DiffUtil实现局部刷新
}

4. 调用示例

在页面拿到原始消息数据后,调用预处理方法再传给Adapter即可:

// 示例:拿到接口返回的原始消息列表
val rawChatList = api.getChatMessageList()
// 预处理
val processedList = processChatList(rawChatList)
// 传给Adapter
chatAdapter.updateList(processedList)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:36:02