Ein Stateful ViewModel
Heute möchte ich Ihnen eine praktische ViewModel- Klassenvariante vorstellen , die ich geschrieben habe und die ich schon seit einiger Zeit verwende.
Um den Status eines ViewModels zu verwalten und verfügbar zu machen , kann man die beliebte Kotlins-API StateFlow verwenden .
Stellen wir unseren UI-Status mit der folgenden Datenklasse dar:
data class UiState(
val isLoading: Boolean = false,
val hasError: Boolean = false,
val data: ScreenData? = null,
)
Um den obigen Zustand der Benutzeroberfläche zugänglich zu machen, verwenden wir eine Klasse, die das ViewModel erweitert:
class ScreenViewModel() : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
suspend fun fetchData() {
_uiState.update { state ->
state.copy(
isLoading = true,
hasError = false
)
}
val fetchedData = fetchDataFromNetwork()
val failed = fetchedData is Error
val data = fetchedData as? Data
_uiState.update { state ->
state.copy(
isLoading = false,
hasError = failed,
data = data,
)
}
}
}
Nehmen wir weiter an, dass wir eine weitere Funktion benötigen, die die Daten aktualisiert, dann würden wir so etwas schreiben:
suspend fun updateData(newData: Data) {
_uiState.update { state ->
state.copy(
isLoading = true,
hasError = false
)
}
val update = updateAndGetData(newData)
val failed = update is Error
val data = update as? Data
_uiState.update { state ->
state.copy(
isLoading = false,
hasError = failed,
data = data,
)
}
}
Wie viele von Ihnen haben es wahrscheinlich auch getan, ich habe dieses Muster schon oft verwendet. Also habe ich beschlossen, ein erweitertes generisches ViewModel zu schreiben, ich habe es StatefulViewModel genannt:
open class StatefulViewModel<T>(initState: T): ViewModel() {
private val _uiState = MutableStateFlow(initState)
val uiState = _uiState.asStateFlow()
protected fun updateState(f: T.() -> T) {
_uiState.update(f)
}
protected fun updateState(newState: T) {
_uiState.value = newState
}
protected val state: T
get() = _uiState.value
}
Mit dieser neuen Klasse kann unser oben beschriebenes ScreenViewModel wie folgt umgestaltet werden:
class ScreenViewModel : StatefulViewModel<UiState>(UiState()) {
suspend fun fetchData() {
updateState {
copy(isLoading = true, hasError = false)
}
val fetchedData = fetchDataFromNetwork()
val failed = fetchedData is Error
val data = fetchedData as? Data
updateState {
copy(isLoading = false, hasError = failed, data = data)
}
}
suspend fun updateData(newData: Data) {
updateState {
copy(isLoading = true, hasError = false)
}
val update = updateAndGetData()
val failed = update is Error
val data = update as? Data
updateState {
copy(isLoading = false, hasError = failed, data = data)
}
}
}
Ich hoffe, dass Sie die StatefulViewModel- Klasse nützlich finden und sie in Ihrem nächsten Projekt verwenden!

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































