StateFlow не обновляется при вставке записей в базовую базу данных Room.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 StateFlow не обновляется при вставке записей в базовую базу данных Room.

Сообщение Anonymous »

В моей ViewModel расписание StateFlow представляет все значения в базе данных, и StateFlow selectedDateAvailableTime основан на этом. Я заполняю свою базу данных с помощью fillScheduleEntities(), но пользовательский интерфейс, собирающий selectedDateAvailableTime, не обновляется новыми значениями: какая бы дата ни была выбрана, время никогда не отображается.
Моя ViewModel:

Код: Выделить всё

@HiltViewModel
class CalendarViewModel @Inject constructor(private val scheduleDao: ScheduleDao) : ViewModel() {
init {
fillScheduleEntities()
}

val timeFormat = LocalTime.Format { hour(); char(':'); minute(); char(':'); second() }

val schedule: StateFlow = scheduleDao.getAll().stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = emptyList(),
)
private val selectedDate = MutableStateFlow(LocalDate(2026, 1, 1))
val selectedDateUiState = selectedDate.asStateFlow()
val selectedDateAvailableTime: StateFlow = selectedDate.map { date ->
getAvailableTimeForDate(date)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList(),
)

fun onDateChanged(dateMillis: Long?) {
if (dateMillis != null) {
selectedDate.value = Instant.fromEpochMilliseconds(dateMillis)
.toLocalDateTime(TimeZone.currentSystemDefault()).date
}
}

private fun getAvailableTimeForDate(date: LocalDate): List {
val availableTime = mutableListOf()
try {
if (date.year > 2000) {
availableTime.plus(schedule.value.firstOrNull { it.date == date }?.availableTime)
}
} catch (e: Exception) {
availableTime.clear()
Log.e("CalendarViewModel.getAvailableTimeForDate", e.toString())
throw (e)
}
return availableTime
}

private fun getScheduleEntities(): List {
val scheduleEntities = mutableListOf()
try {
val startDate = LocalDate(2000, 1, 1)
val endDate = java.time.LocalDate.now().toKotlinLocalDate()
val startTime = java.time.LocalTime.of(9, 0, 0)
val endTime = java.time.LocalTime.of(18, 0, 0)
val timeList = generateSequence(startTime) { it.plusMinutes(30) }
.takeWhile { it   item.format(timeFormat) }

@TypeConverter
fun stringToListLocalTime(value: String?): List? =
value?.split(',')?.map { item -> LocalTime.parse(item.trim(), timeFormat) }
}
Дао:

Код: Выделить всё

@Dao
interface ScheduleDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(scheduleEntities: List): List

@Query("SELECT * FROM ScheduleEntity")
fun getAll(): Flow
}
Мой макет создания:

Код: Выделить всё

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainLayout() {
val viewModel: CalendarViewModel = hiltViewModel()

val schedule by viewModel.schedule.collectAsStateWithLifecycle()
val selectedDate by viewModel.selectedDateUiState.collectAsStateWithLifecycle()
val time by viewModel.selectedDateAvailableTime.collectAsStateWithLifecycle()
val datePickerState = rememberDatePickerState(initialSelectedDate = selectedDate.toJavaLocalDate())

LaunchedEffect(datePickerState.selectedDateMillis) {
viewModel.onDateChanged(datePickerState.selectedDateMillis)
}

Column {
DatePicker(datePickerState)

LazyVerticalGrid(
columns = GridCells.Fixed(7),
) {
items(time) { curTime ->
Text(curTime.format(viewModel.timeFormat))
}
}
}
}
Репозиторий моего проекта

Подробнее здесь: https://stackoverflow.com/questions/798 ... m-database
Ответить

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

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

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

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

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