Jetpack Compose Grundlagen: Moderne Android-UI mit Kotlin

Wer heute eine neue Android-App startet, kommt an Jetpack Compose kaum noch vorbei. Googles modernes UI-Toolkit hat das klassische XML-Layout-System weitgehend abgelöst und definiert neu, wie Benutzeroberflächen auf Android gebaut werden. Statt Layouts in XML zu beschreiben und sie zur Laufzeit aufzublasen, schreibst du deine komplette Oberfläche direkt in Kotlin – deklarativ, kompakt und nah am tatsächlichen Datenfluss deiner App. Dieser Artikel führt dich durch die wichtigsten Grundlagen, ohne dass du dafür schon ein Compose-Profi sein musst.

Deklarativ statt imperativ: Der grundlegende Unterschied

Das alte View-System war imperativ. Du hast ein Layout aufgebaut, dir Referenzen auf einzelne Views geholt (per findViewById oder ViewBinding) und diese dann Schritt für Schritt verändert: textView.setText(...), button.setEnabled(false), recyclerView.adapter.notifyDataSetChanged(). Die UI und der Zustand der App mussten dabei ständig manuell synchron gehalten werden – eine häufige Fehlerquelle.

Jetpack Compose ist deklarativ. Du beschreibst nicht, wie sich die UI von einem Zustand in den nächsten verändert, sondern nur, wie sie für einen gegebenen Zustand aussehen soll. Ändert sich der Zustand, zeichnet Compose die betroffenen Teile automatisch neu. Dieses Prinzip kennt man bereits aus React im Web oder SwiftUI auf iOS – Compose bringt es nach Android.

Composable-Funktionen: Die Bausteine

Das Herzstück von Compose sind Composable-Funktionen. Das sind ganz normale Kotlin-Funktionen, die mit der Annotation @Composable markiert sind. Eine simple Begrüßung sieht so aus:

Diese Modularität ist einer der größten Vorteile: Statt einer monolithischen XML-Datei mit 300 Zeilen baust du deine UI aus kleinen, testbaren Funktionen, die jeweils eine klare Aufgabe haben.

State und Recomposition: Das Reaktivitätsmodell

Compose-UI ist eine Funktion deines State (Zustand). Wann immer sich dieser Zustand ändert, führt Compose die betroffenen Composable-Funktionen erneut aus, um die UI zu aktualisieren. Diesen Vorgang nennt man Recomposition.

Damit Compose Änderungen überhaupt bemerkt, brauchst du beobachtbaren Zustand. Das erreichst du mit mutableStateOf in Kombination mit remember:

Ein typischer Zähler nutzt var count by remember { mutableStateOf(0) }. Beim Klick auf einen Button erhöhst du count einfach um eins – die Anzeige aktualisiert sich von selbst, weil Compose die Recomposition auslöst. Kein manuelles setText mehr.

State Hoisting

Ein zentrales Muster ist das State Hoisting (Zustand nach oben ziehen). Statt den Zustand tief in einer Composable-Funktion zu verstecken, hebst du ihn auf eine höhere Ebene und reichst Werte sowie Callbacks nach unten weiter. Das macht deine Composables zustandslos (stateless) und damit leichter testbar, wiederverwendbar und vorhersagbar. Die Faustregel: State so weit oben halten, wie nötig, aber so weit unten, wie möglich.

Modifier: Aussehen und Verhalten anpassen

Fast jedes Composable nimmt einen Modifier-Parameter entgegen. Modifier sind eine verkettbare Sammlung von Anweisungen, die Größe, Abstände, Hintergrund, Klickverhalten und vieles mehr steuern. Sie ersetzen die unzähligen XML-Attribute aus dem alten System:

Wichtig ist die Reihenfolge: Modifier werden von links nach rechts angewendet. padding(8.dp).background(Color.Red) ergibt ein anderes Bild als background(Color.Red).padding(8.dp). Das wirkt anfangs ungewohnt, wird aber schnell intuitiv. Einheiten gibt man in dp (density-independent pixels) für Größen und in sp (scale-independent pixels) für Schriftgrößen an – genau wie früher, nur jetzt typsicher direkt im Kotlin-Code.

Layouts: Column, Row und Box

Compose stellt drei grundlegende Layout-Composables bereit, mit denen sich praktisch jede Oberfläche bauen lässt:

Ausrichtung steuerst du über Parameter wie horizontalAlignment, verticalArrangement oder contentAlignment. Für lange, scrollbare Listen nutzt du LazyColumn und LazyRow. Diese sind das Compose-Pendant zum RecyclerView: Sie rendern nur die tatsächlich sichtbaren Elemente und sind dadurch auch bei tausenden Einträgen performant – ganz ohne Adapter, ViewHolder und den ganzen Boilerplate-Code.

Vorschau und schneller Entwicklungs-Loop

Ein praktischer Pluspunkt ist die @Preview-Annotation. Markierst du eine Composable-Funktion damit, rendert Android Studio sie direkt in der IDE – ohne die App auf einem Gerät oder Emulator starten zu müssen. Du kannst mehrere Previews mit unterschiedlichen Parametern, Themes oder Bildschirmgrößen anlegen und so deine UI in vielen Varianten parallel im Blick behalten. Zusammen mit Live Edit verkürzt das den Iterationszyklus enorm.

Der Umstieg von XML-Views

Du musst keine bestehende App komplett neu schreiben. Compose ist interoperabel mit dem alten View-System: Mit ComposeView bettest du Compose in ein XML-Layout ein, mit AndroidView nutzt du klassische Views innerhalb von Compose. So lässt sich eine App schrittweise migrieren – Bildschirm für Bildschirm – statt in einem riskanten Big-Bang-Umbau.

Wer von XML kommt, sollte sich vor allem von der Vorstellung lösen, die UI selbst aktiv verändern zu müssen. In Compose verändert man Daten, und die UI folgt. Dieses Umdenken ist die eigentliche Lernkurve – die Syntax selbst ist schnell verinnerlicht.

Praktische Tipps für den Einstieg

Häufige Fragen

Ersetzt Jetpack Compose XML-Layouts komplett?

Für neue Projekte empfiehlt Google klar Compose. XML-Layouts funktionieren weiterhin und werden gepflegt, gelten aber als Legacy-Ansatz. In der Praxis koexistieren beide oft eine Weile, weil Apps schrittweise migriert werden.

Brauche ich Kotlin für Compose?

Ja. Jetpack Compose ist ausschließlich für Kotlin konzipiert und nutzt dessen Sprachfeatures intensiv. Java-Code kann zwar parallel in derselben App existieren, aber Composables selbst schreibst du in Kotlin.

Ist Compose langsamer als das alte View-System?

In der Anfangszeit gab es Performance-Diskussionen, vor allem im Debug-Build. Mit aktuellen Versionen und aktiviertem Baseline-Profil ist Compose im Release-Build praktisch ebenbürtig und in vielen Szenarien sogar effizienter, weil unnötige Layout-Durchläufe entfallen.

Wie tief muss ich Recomposition verstehen?

Für den Einstieg reicht das mentale Modell „Zustand ändert sich, betroffene Composables laufen erneut". Für performante Apps lohnt es sich später, Themen wie Stabilität von Parametern, derivedStateOf und das Vermeiden unnötiger Recompositions zu vertiefen.

Wo lerne ich Compose am besten?

Googles offizielle „Now in Android"-Beispiel-App und die Compose-Pathways-Kurse sind ein hervorragender Startpunkt. Ergänzend hilft es, eigene kleine Apps zu bauen und konsequent mit der @Preview-Funktion zu experimentieren.