Переключение с .first() на .collect{} в потоке остановило появление данных на экране.Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Переключение с .first() на .collect{} в потоке остановило появление данных на экране.

Сообщение Anonymous »

Я создал модель представления с Flow и Room, которая соединила мои переменные в UiState с Room, используя .first() в качестве Codelabs показали мне. Я заметил, что использование .first() — не лучшая идея, потому что, когда я вставлял что-то в базу данных, экран не обновлялся автоматически, показывая новое значение.
Итак, я узнал, что использование Collect{} — это правильный подход к постоянному автоматическому обновлению переменных uistate. После его изменения мой экран не показывает никаких данных, и я не могу понять, почему. Как мне найти проблему? Я добавляю сюда модель представления.
Вы можете увидеть комментарий к старому коду. Я имею в виду код с .first(), который работал, но без автоматического обновления. За прокомментированным кодом следует новый код с функцией Collect{}, который вообще не работает.
data class UiState(
val searchResult: List = listOf(),
val favorites: List = listOf(),
val selectedAirport: Airport? = null,
val flightsForSelectedAirport: List = listOf()
)

class FlightsScreenViewModel(
private val flightRepository: FlightsRepository,
private val userPreferencesRepository: UserPreferencesRepository
) : ViewModel() {
var uiState by mutableStateOf(UiState())
private set

var searchText by mutableStateOf("")
private set

init {
viewModelScope.launch {
// searchText = userPreferencesRepository.searchText.first()
userPreferencesRepository.searchText.collect{ searchText = it }
updateSearchResults()
}
}

private suspend fun updateSearchResults() {
// val searchResult = if (searchText != "")
// flightRepository.getAirportsByIatOrName(searchText).filterNotNull().first()
// else
// emptyList()
//
// val favorites = flightRepository.getFavorites().filterNotNull().first()
//
// uiState = uiState.copy(
// searchResult = searchResult,
// favorites = favorites
// )

if (searchText != "") {
flightRepository.getAirportsByIatOrName(searchText).filterNotNull().collect{ uiState = uiState.copy(searchResult = it) }
} else {
uiState = uiState.copy(favorites = emptyList())
}

flightRepository.getFavorites().filterNotNull().collect{ uiState = uiState.copy(favorites = it) }
}

fun updateSearchText(searchText: String) {
this.searchText = searchText
viewModelScope.launch {
userPreferencesRepository.saveSearchTextPreference(searchText)
updateSearchResults()
}
}

fun selectAirport(airport: Airport?) {
viewModelScope.launch {
// val flightsForSelectedAirport = if (airport == null) {
// emptyList()
// } else {
// flightRepository.getAllDifferentAirports(airport.id).first()
// }
//
// uiState = uiState.copy(
// selectedAirport = airport,
// flightsForSelectedAirport = flightsForSelectedAirport
// )

if (airport != null) {
flightRepository.getAllDifferentAirports(airport.id).collect{ uiState = uiState.copy(flightsForSelectedAirport = it) }
} else {
uiState = uiState.copy(flightsForSelectedAirport = emptyList())
}

uiState = uiState.copy(selectedAirport = airport)
}
}

fun insertFavorite(depart: String, arrive: String) {
if (!uiState.favorites.checkIfFavoriteExists(depart, arrive)) {
val favorite = Favorite(departureCode = depart, destinationCode = arrive)
viewModelScope.launch {
flightRepository.insertFavorite(favorite)
}
}
}

companion object {
val factory : ViewModelProvider.Factory = viewModelFactory {
initializer {
FlightsScreenViewModel(
FlightSearchApplication().container.flightRepository,
FlightSearchApplication().container.userPreferencesRepository
)
}
}
}
}

fun List.checkIfFavoriteExists(depart: String, arrive: String): Boolean{
for (favorite in this){
if (favorite.departureCode == depart && favorite.destinationCode == arrive)
return true
}
return false
}

Это код, который должен отображать содержимое на экране, но ничего не показывает после обновления с .first() на .collect{}< /p>
LazyColumn(
modifier = Modifier.padding(8.dp)
) {
items(uiState.searchResult) { airport ->
AirportDetail(airport, onAirportSelected)
}
}
uiState.selectedAirport?.let {
FlightsForAirport(
airport = uiState.selectedAirport,
arrivals = uiState.flightsForSelectedAirport,
favorites = uiState.favorites,
onFavoriteSelected = onFavoriteSelected
)
}


Подробнее здесь: https://stackoverflow.com/questions/785 ... -on-screen
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»