Mehrere Flows mit combine() verbinden – Live-Validierung ohne Wirrwarr
Wenn ein Ergebnis von mehreren sich ändernden Werten abhängt – z. B. ob ein Formular abgeschickt werden darf – verbindest du die Flows mit combine(). Das reagiert automatisch, sobald sich irgendeiner ändert.
Oft hängt ein Wert von mehreren anderen ab, die sich unabhängig ändern: Der „Anmelden"-Button wird erst aktiv, wenn E-Mail und Passwort gültig sind. Solche Abhängigkeiten von Hand zu verdrahten wird schnell unübersichtlich. Mit combine() verbindest du mehrere Flows zu einem – und der neue Flow gibt automatisch einen neuen Wert aus, sobald sich irgendeiner der Eingaben ändert.
Formular-Validierung im ViewModel
class LoginViewModel : ViewModel() {
val email = MutableStateFlow("")
val password = MutableStateFlow("")
// canSubmit wird bei jeder Änderung von email ODER password neu berechnet
val canSubmit: StateFlow<Boolean> = combine(email, password) { mail, pw ->
mail.contains("@") && pw.length >= 8
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = false,
)
fun onEmailChange(v: String) { email.value = v }
fun onPasswordChange(v: String) { password.value = v }
}Im Compose-UI bindest du das direkt an den Button:
val canSubmit by vm.canSubmit.collectAsStateWithLifecycle()
Button(onClick = vm::submit, enabled = canSubmit) {
Text("Anmelden")
}Warum das so angenehm ist
- Eine Quelle der Wahrheit. Statt in jedem
onChangevon Hand zu prüfen, steckt die Regel an genau einer Stelle. Kommt ein drittes Feld dazu, nimmst du es einfach incombine(email, password, agb)mit auf. - Immer aktuell.
combinewartet, bis jeder Flow mindestens einen Wert hatte, und feuert danach bei jeder Änderung mit den jeweils neuesten Werten aller Quellen. stateInmacht daraus einenStateFlowmit Startwert – ideal fürs UI.WhileSubscribed(5_000)stoppt die Berechnung, wenn für 5 Sekunden niemand mehr zuhört (z. B. App im Hintergrund), und spart so Ressourcen.
Verwandt: Für „nimm immer nur das neueste und verwirf laufende Arbeit" – etwa bei einer Live-Suche – ist flatMapLatest das passende Werkzeug. combine ist für „alle Werte zusammenführen".
Du brauchst eine App mit reaktiven, wartbaren Formularen und Zuständen? Melde dich.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
stateIn und shareIn – aus einem kalten Flow wird geteilter Zustand
Jeder Sammler eines kalten Flows startet die Arbeit neu – zwei Beobachter, zwei Datenbankabfragen. stateIn und shareIn machen daraus einen Strom, den sich alle teilen, samt aktuellem Wert und Abschalten bei Inaktivität.
viewModelScope – Coroutinen, die mit dem Bildschirm verschwinden
Eine Coroutine, die nach dem Schließen des Bildschirms weiterläuft, schreibt in ein ViewModel, das niemand mehr sieht – und hält im schlimmsten Fall die ganze Activity im Speicher. viewModelScope beendet sie automatisch.
Nach mehreren Kriterien sortieren – sortedWith, compareBy und thenBy
Erst nach Priorität, dann nach Datum, und die ohne Termin ganz nach hinten: Solche Sortierungen werden mit einem handgeschriebenen Comparator schnell unleserlich. Kotlin hat dafür eine Baukastenschreibweise.