Я инициализировал общий ChatviewModel на главном экране, который получает начальные данные SeargitListState и наблюдает об обновлении базы данных в реальном времени из репозитория. Код отлично работает! Государство обновляется правильно, даже когда я не на главном экране. Он даже обновляется в чате . Тем не менее, пользовательский интерфейс не обновляется, даже если контент, показанный на экране, несоответствует тем, что в штате. Я должен перезагрузить экран, чтобы он обновил. Пожалуйста, помогите мне выяснить, почему это происходит. Заранее спасибо.@HiltViewModel
class ChatViewModel @Inject constructor(
private val loadUserAva: LoadUserAva,
private val subscribeToConversationsUseCase: SubscribeToConversationsUseCase,
savedStateHandle: SavedStateHandle
) : ViewModel() {
private val _conversationListState =
MutableStateFlow(emptyList())
val conversationListState = _conversationListState.asStateFlow()
private val _avatarUrls = MutableStateFlow(emptyMap())
val avatarUrls = _avatarUrls.asStateFlow()
private var _initialized = false
fun initialize(userId: String) {
if (_initialized) return
Log.d("ChatViewModel", "ChatViewModel initialized")
Log.d("ChatViewModel", "User ID from saved state: $userId")
getConversationList(userId)
loadAvatar(userId) // Tải avatar cho người dùng hiện tại
_initialized = true
}
private fun getConversationList(userId: String) {
subscribeToConversationsUseCase(userId)
.onEach { response ->
// Tải avatar cho tất cả otherId khi danh sách cuộc trò chuyện được cập nhật
if (response is Response.Success) {
Log.d("ChatViewModel", "Conversation list updated with response: $response")
_conversationListState.update {
response.data?.toList() ?: emptyList()
}
response.data?.forEach { conversation ->
val otherId = if (conversation.conversation!!.firstUserId == userId) {
conversation.conversation.secondUserId
} else {
conversation.conversation.firstUserId
}
loadAvatar(otherId)
println("Loaded conversations with length ${response.data.size}")
}
}
}.launchIn(viewModelScope)
}
private fun loadAvatar(userId: String) {
println("Loading avatar for user $userId...")
viewModelScope.launch {
// Kiểm tra xem avatar đã được tải chưa để tránh tải lại
if (_avatarUrls.value[userId] == null) {
val result = loadUserAva(userId)
println("Avatar result for user $userId: $result")
_avatarUrls.value = _avatarUrls.value.toMutableMap().apply {
this[userId] = result
}
}
}
}
}
< /code>
chatscreen.kt
@Composable
fun ChatScreen(
navController: NavController,
userId: String,
messageCount: Int,
viewModel: ChatViewModel = hiltViewModel()
) {
val conversationListState by viewModel.conversationListState.collectAsStateWithLifecycle()
Log.d("ChatScreen", "Conversation List State Updated")
val avatarUrls by viewModel.avatarUrls.collectAsStateWithLifecycle()
val isLoading = false
if (isLoading) {
ShimmerScreen(navController, userId, 2, "Chat", R.drawable.chat_unread_svgrepo_com)
} else {
Scaffold(
bottomBar = {
BottomNavigationBar(navController, userId, 2, messageCount)
}
) { innerPadding ->
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.padding(innerPadding)
) {
Header("Chat", R.drawable.chat_icon_header)
TextButton(onClick = {
Log.d("ChatScreen", "Current state: $conversationListState")
}) {
Text("Log Conversation List State")
}
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(
conversationListState.size,
key = { conversationListState[it].conversation?.id ?: it }) { index ->
val conversation = conversationListState[index]
val otherId = if (conversation.conversation!!.firstUserId == userId) {
conversation.conversation.secondUserId
} else {
conversation.conversation.firstUserId
}
val name = conversation.otherName
val message = conversation.lastMessage?.content.toString()
val time = conversation.lastMessage?.timeSent.toCustomString()
val imageRes = R.drawable.avatar_1
val haveSeen = conversation.lastMessage?.isRead ?: false
val isOnline = true // TODO: Implement online function
val profilePicUrl = avatarUrls[otherId]?.let { response ->
when (response) {
is Response.Success -> response.data
is Response.Loading -> null
is Response.Failure -> null
Response.Idle -> TODO()
}
}
ChatItem(
navController = navController,
userId = userId,
otherId = otherId,
otherName = name,
message = message,
time = time,
imageRes = imageRes,
haveSeen = haveSeen,
isOnline = isOnline,
profilePicUrl = profilePicUrl
)
}
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... s-the-same
Android Kotlin: состояние пользовательского интерфейса обновляется, но пользовательский интерфейс остается прежним ⇐ Android
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение