HomeScreen: отображает бюджет и список продуктов.
NewItemScreen: позволяет добавлять новые продукты.
ItemDetailsScreen: показывает подробную информацию о выбранный продукт.
EditItemScreen: позволяет редактировать существующий продукт.
Приложение использует ViewModel для управления данными, связанными с пользовательским интерфейсом, и у меня возникла проблема с EditItemScreen.
Описание проблемы:
Когда я пытаюсь обновить сведения об элементе в EditItemScreen, кажется, что значения входят в цикл, чередуя новые и старые значения. Иногда он вообще не обновляется или требуется некоторое время между обновлениями.
Код:
Вот соответствующий код:
EditItemViewModel
Код: Выделить всё
class EditItemViewModel(
savedStateHandle: SavedStateHandle,
private val itemsRepository: ItemsRepository
): ViewModel() {
companion object {
private const val TAG = "Edit Item"
}
var editItemUiState by mutableStateOf(ItemUiState())
private set
private val itemId: Int = checkNotNull(savedStateHandle[EditItemDestination.itemIdArg])
init {
viewModelScope.launch {
val item = itemsRepository.getItemStream(itemId)
.filterNotNull()
.first()
editItemUiState = item.toItemUiState(isEntryValid = true)
}
}
fun updateEditUiState(itemDetails: ItemDetails) {
editItemUiState =
editItemUiState.copy(
itemDetails = itemDetails,
isEntryValid = validateInput(itemDetails)
)
}
fun updateEditTag(tag: String) {
editItemUiState =
editItemUiState.copy(tag = tag)
}
fun updateItem() {
val item = editItemUiState.itemDetails.toItem()
if (validateInput()) {
viewModelScope.launch {
try {
itemsRepository.updateItem(item)
// Añadir un pequeño retraso para asegurar que la actualización se complete
delay(100)
// Recargar el item después de la actualización
val updatedItem = itemsRepository.getItemStream(item.id).filterNotNull().first()
editItemUiState = updatedItem.toItemUiState(isEntryValid = true)
} catch (e: Exception) {
Log.e(TAG, "Item could not be updated", e)
}
}
}
}
private fun validateInput(itemDetails: ItemDetails = editItemUiState.itemDetails): Boolean {
return with(itemDetails) {
name.isNotBlank() && price.isNotBlank()
}
}
}
Код: Выделить всё
@Dao
interface ItemDao {
@Insert(onConflict = OnConflictStrategy.ABORT)
suspend fun insert(item: Item)
@Update
suspend fun update(item: Item)
@Delete
suspend fun delete(item: Item)
@Query("SELECT * FROM items")
fun getAll(): Flow
@Query("SELECT * FROM items WHERE id = :id")
fun getItem(id: Int): Flow
@Query("SELECT * FROM items WHERE price < :price")
fun getByPrice(price: Double): Flow
}
Код: Выделить всё
interface ItemsRepository {
fun getAllItemsStream(): Flow
fun getItemStream(id: Int): Flow
fun getByPrice(price: Double): Flow
suspend fun insertItem(item: Item)
suspend fun updateItem(item: Item)
suspend fun deleteItem(item: Item)
}
class OfflineItemsRepository(
private val itemDao: ItemDao
): ItemsRepository {
override fun getAllItemsStream(): Flow = itemDao.getAll()
override fun getItemStream(id: Int): Flow = itemDao.getItem(id)
override fun getByPrice(price: Double): Flow = itemDao.getByPrice(price)
override suspend fun insertItem(item: Item) = itemDao.insert(item)
override suspend fun updateItem(item: Item) {
withContext(Dispatchers.IO) {
itemDao.update(item)
}
}
override suspend fun deleteItem(item: Item) = itemDao.delete(item)
}
Я пробовал изменить способ обработки состояния в EditItemViewModel, я изменил функцию updateItem(), я изменил OnConflictStrategy в ItemDao и попробовал WithContext в репозитории.
p>
Нет изменений
Буду признателен за помощь

Подробнее здесь: https://stackoverflow.com/questions/787 ... ata-update