Mein ViewModel (teilweise)
Code: Select all
@HiltViewModel
class CalendarViewModel @Inject constructor(private val scheduleDao : ScheduleDao) : ViewModel() {
private val selectedDate = MutableStateFlow
(LocalDate(2026, 1, 1))
val selectedDateUiState = selectedDate.asStateFlow()
val schedule : StateFlow = scheduleDao.getAll().stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = emptyList()
)
fun onDateChanged(dateMillis : Long?) {
if(dateMillis != null) {
selectedDate.value = Instant.fromEpochMilliseconds(dateMillis)
.toLocalDateTime(TimeZone.currentSystemDefault()).date
}
}
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? {
return value?.split(',')?.map { item -> LocalTime.parse(item.trim(), timeFormat) }
}
}
Code: Select all
@Dao
interface ScheduleDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertOne(vararg scheduleEntity : ScheduleEntity)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(scheduleEntities : List): List
@Delete
suspend fun delete(scheduleEntity : ScheduleEntity)
@Query("SELECT * FROM ScheduleEntity")
fun getAll() : Flow
}
Code: Select all
@Database(entities = [ScheduleEntity::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class CalendarDatabase : RoomDatabase() {
abstract fun scheduleDao() : ScheduleDao
companion object {
var INSTANCE : CalendarDatabase? = null
fun getDatabase(context: Context) : CalendarDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(context.applicationContext, CalendarDatabase::class.java, "tasks")
.enableMultiInstanceInvalidation()
.build()
INSTANCE = instance
return instance
}
}
}
}
@Module
@InstallIn(SingletonComponent::class)
object TasksModule {
@Provides
@Singleton
fun provideApplicationScope(): CoroutineScope {
return CoroutineScope(SupervisorJob() + Dispatchers.IO)
}
@Provides
@Singleton
fun provideDatabase(
@ApplicationContext context: Context) : CalendarDatabase = CalendarDatabase.getDatabase(context)
@Provides
@Singleton
fun provideScheduleDao(calendarDatabase : CalendarDatabase) : ScheduleDao = calendarDatabase.scheduleDao()
}
Code: Select all
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainLayout(modifier: Modifier? = null, viewModel : CalendarViewModel = hiltViewModel()) {
viewModel.fillScheduleEntities()
val selectedDate by viewModel.selectedDateUiState.collectAsState()
val schedule by viewModel.schedule.collectAsStateWithLifecycle()
val datePickerState = rememberDatePickerState(initialSelectedDate = selectedDate.toJavaLocalDate())
LaunchedEffect(datePickerState.selectedDateMillis) {
viewModel.onDateChanged(datePickerState.selectedDateMillis)
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top,
modifier = (modifier ?: Modifier)
.fillMaxWidth()
.fillMaxHeight()
) {
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
.wrapContentHeight()
) {
DatePicker(
state = datePickerState,
modifier = Modifier.size(400.dp))
}
SelectedDateAvailableTimeList(Modifier.weight(1f), viewModel)
}
}
@Composable
fun SelectedDateAvailableTimeList(modifier : Modifier, viewModel : CalendarViewModel = hiltViewModel()) {
val time by viewModel.selectedDateAvailableTime.collectAsState()
LazyVerticalGrid(
columns = GridCells.Fixed(7),
userScrollEnabled = false,
horizontalArrangement = Arrangement.spacedBy(space = 10.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
modifier = modifier.fillMaxWidth().wrapContentHeight().padding(0.dp, 10.dp)
) {
items(time) { curTime ->
BasicTextField(
modifier = Modifier
.wrapContentSize(Alignment.Center),
textStyle = TextStyle(
textAlign = TextAlign.Center,
fontSize = 10.sp,
fontWeight = FontWeight.Normal,
color = Black),
readOnly = true,
value = curTime.format(viewModel.timeFormat),
onValueChange = {},
)
}
}
}
Code: Select all
private val refreshTrigger = MutableSharedFlow(replay = 1).apply { tryEmit(Unit) }
val schedule : StateFlow = refreshTrigger.flatMapLatest { scheduleDao.getAll() }.stateIn(
scope = viewModelScope,
started = SharingStarted.Lazily,
initialValue = emptyList()
)
...
scheduleEntities = getScheduleEntities()
val scheduleIds = scheduleDao.insertAll(scheduleEntities)
refreshTrigger.emit(Unit)
Mobile version