我正在将消息保存在房间数据库中,并希望在用户重新打开片段时显示它们,两侧的消息就像 Whatsapp 聊天片段,但当系统给出响应时,用户消息被替换并且重新打开后不显示该应用程序也仅系统生成的消息显示在 reyclcer 视图中。
实体类是
@Entity(tableName = "messages")
data class Conversation(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
@ColumnInfo(name = "sent") val sent: String,
@ColumnInfo(name = "received") var received : String,
@ColumnInfo(name = "timestamp") val timestamp: Long
)
这是viewcreated部分的主要片段
database = ConversationDatabase.getDatabase(requireContext())
conversationViewModel.getUserMessages().observe(viewLifecycleOwner) { messages ->
messageRVAdapter.setconversationHistory(messages)
}
conversationViewModel.getAllMessages().observe(viewLifecycleOwner) { messages ->
messageRVAdapter.updateMessages(messages)
}
}
private fun getAllMessages(dao: ConversationDao, messageRVAdapter: MessageRVAdapter) {
val userMessages = dao.getUserMessages()
val allMessages = dao.getAllMessages()
userMessages.observe(viewLifecycleOwner) { userConversationList ->
val userMessages = userConversationList.map { conversation ->
MessageRVModel(conversation.sent, conversation.received, System.currentTimeMillis())
}
messageRVAdapter.setconversationHistory(userMessages)
}
allMessages.observe(viewLifecycleOwner) { allConversationList ->
val allMessages = allConversationList.map { conversation ->
MessageRVModel(conversation.sent, conversation.received, System.currentTimeMillis())
}
messageRVAdapter.setconversationHistory(allMessages)
}
}
这是适配器类
class MessageRVAdapter(private var messageList: ArrayList<MessageRVModel>):
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class RequestMessageViewHolder(ItemView: View): RecyclerView.ViewHolder(ItemView){
val requestMsgTV: TextView = itemView.findViewById(R.id.request_text)
}
class ResponseMessageViewHolder(ItemView: View): RecyclerView.ViewHolder(ItemView){
val responseMsgTV: TextView = itemView.findViewById(R.id.response_text)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View
// return if(viewType == 0){
return when (viewType) {
0 -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.request_rv_item, parent, false)
RequestMessageViewHolder(view)
}
// else{
1 -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.response_rv_item, parent, false)
ResponseMessageViewHolder(view)
}
else -> throw IllegalArgumentException("Invalid view type")
}
}
fun addMessage(messages: MessageRVModel) {
messageList.add(messages)
notifyItemInserted(messageList.size - 1)
}
fun updateMessages(messages: List<MessageRVModel>) {
val previousSize = messageList.size
messageList.clear()
messageList.addAll(messages)
messageList.sortBy { it.timestamp }
notifyDataSetChanged()
}
fun setconversationHistory(messages: List<MessageRVModel>) {
messageList.clear()
messageList.addAll(messages)
notifyDataSetChanged()
}
}
这是视图模型类
class ConversationViewModel(application: Application) : AndroidViewModel(application) {
fun setConversationHistory(): LiveData<List<MessageRVModel>> {
return chatBot.getAllMessages()
} fun getUserMessages(): LiveData<List<MessageRVModel>> {
return chatBot.getUserMessages()
} fun getAllMessages(): LiveData<List<MessageRVModel>> {
return chatBot.getAllMessages().map { conversationList ->
conversationList.map { conversation ->
MessageRVModel(conversation.sent, conversation.received, conversation.timestamp)
}
}
} }
这是聊天机器人类
class ChatBot(private val conversationDao: ConversationDao) {
suspend fun insertMessage(sent: String, received: String) {
val timestamp = System.currentTimeMillis()
val conversation = Conversation(id = 0, sent = sent, received = received, timestamp = timestamp)
withContext(Dispatchers.IO) {
conversationDao.insertMessage(conversation)
}
}
}
fun getAllMessages(): LiveData<List<MessageRVModel>> {
return conversationDao.getAllMessages().map { conversationList ->
conversationList.map { conversation ->
MessageRVModel(conversation.sent, conversation.received, conversation.timestamp)
}
}
}
fun getUserMessages(): LiveData<List<MessageRVModel>> {
return conversationDao.getUserMessages().map { conversationList ->
conversationList.map { conversation ->
MessageRVModel(conversation.sent, conversation.received, conversation.timestamp)
}
}
}}
这就是道
@Dao
interface ConversationDao {
@Query("SELECT * FROM messages")
fun getAllMessages(): LiveData<List<Conversation>>
@Query("SELECT * FROM messages WHERE sent = 'me'")
fun getUserMessages(): LiveData<List<Conversation>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMessage(messages: Conversation)
@Delete
suspend fun deleteMessage(messages: Conversation)
}
这是数据类
data class MessageRVModel(
var sent: String,
var received: String,
val timestamp: Long
)
class Message{
var SENT_BY_ME = "me"
var SENT_BY_SYSTEM = "system"
}
我不明白问题所在,导致用户消息无法从数据库获取或显示到回收器视图,并且每次在回收器视图中添加新的 api 响应(如果有)时,它都会替换为 api 响应解决这个问题请帮忙。
发生这种情况可能是因为您在所有对话中都使用相同的
id
。
// id = 0, for all conversations
val conversation = Conversation(id = 0, sent = sent, received = received, timestamp = timestamp)
您已将
id
设置为主键并自动生成,因此您无需设置此项,它将为每个新行自动生成。
@PrimaryKey(autoGenerate = true) val id: Int = 0,
无需 ID 即可进行对话。
// don't specify id
val conversation = Conversation(sent = sent, received = received, timestamp = timestamp)
提示:您还可以使用 Android Studio 的数据库检查器来查看数据库和表以及所有数据。这将帮助您验证确切存储的数据。