Jetpack合成。更新状态时出现问题。只有消息的发送者被更新,其他人都不会被更新。我使用MVI架构
在我的viewModel中有两个用于聊天屏幕的函数,当我在launchedEffect中使用Unit键打开聊天时,getMessages()会立即触发,即getMessages()然后运行一个协程,我在那里更新状态。每个用户的屏幕在那一刻刷新,显示消息。但是当我发送消息时,会触发一个事件,调用viewModel中的sendMessage(),在那里我更新状态,我发现你甚至可以这样更新它,协同程序中的getMessages()再次运行并更新状态。但是,问题是只有消息的发送者更新状态,而其他用户不更新,他们要么需要在键盘上做一些事情,要么重新启动聊天,以便更新状态。
ViewModel中的sendMessage()
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("SimpleDateFormat")
private fun sendMessage(text: String) {
val calendar: Calendar = Calendar.getInstance()
val currentDate = LocalDate.now()
val time = SimpleDateFormat("HH:mm")
val currentMonthName = currentDate.month.getDisplayName(
TextStyle.FULL, Locale.getDefault()
)
val message = MessageModel(
name = Firebase.auth.currentUser?.displayName.toString(),
text = text,
time = time.format(calendar.time),
isMine = false,
sender = Firebase.auth.currentUser?.uid.toString(),
date = currentDate.dayOfMonth.toString() + " " + currentMonthName,
isNewDate = false
)
viewModelScope.launch {
repository.addMessage(message)
_uiState.value.counter += 1
}
}
ViewModel中的getMessages()
private fun getMessages() {
_uiState.update { currentState ->
currentState.copy(
isLoading = true
)
}
viewModelScope.launch {
var i = 0
repository.getMessages()
.map { messages ->
_messagesItemsSenders.add(messages.get(0).sender)
_messagesDates.add(messages.get(0).date)
_messagesPaddingMineAfterLastOther.add(messages.get(0).isMine)
// Check for new sender
if ((_messagesItemsSenders.size > 1) && (!messages.get(0).isMine) and
(_messagesItemsSenders[i] == _messagesItemsSenders[i-1])) {
messages.get(0).isMoreOne = true
}
// Check for new date
messages.get(0).isNewDate =
!((_messagesDates.size > 1) && (_messagesDates[i] == _messagesDates[i-1]))
// Set padding for first message that called "isMine"
messages.get(0).isPaddingMine = (_messagesPaddingMineAfterLastOther.size > 1) &&
(messages.get(0).isMine) and
(_messagesPaddingMineAfterLastOther[i]
!= _messagesPaddingMineAfterLastOther[i-1])
i += 1
ChatViewState(messages = messages, isLoading = false)
}
.collect() { newState ->
_uiState.value = newState
}
}
1条答案
按热度按时间c3frrgcw1#
将接收到的消息存储在一个mutableStateList中,然后在您想要显示消息的任何地方引用该列表。当列表被更新时,(已接收到新消息)调用列表的可组合项将重新组合。