Moderne Anwendungen werden immer stärker design- und damit nutzerzentriert gedacht. Für Nutzer ist die technische Umsetzung selten interessant - sie wird vielmehr vorausgesetzt. Ansprechendes Design, Animationen und eine gute Bedienbarkeit können dagegen einen echten Unterschied machen.
Die Animationen in Android Compose wurden komplett neu gedacht. Der deklarative Ansatz von Jetpack Compose macht das Erstellen von Animationen einfacher und klarer. Schauen wir uns anhand der SenseBox-App verschiedene Arten von Animationen an:
Die Animation für das Erscheinen und Verschwinden wird über die Composable-Funktion AnimatedVisibility umgesetzt, die die folgende Signatur hat:
@Composable
@ComposableInferredTarget
public fun ColumnScope.AnimatedVisibility(
visible: Boolean,
modifier: Modifier,
enter: EnterTransition,
exit: ExitTransition,
label: String,
content: @Composable() (AnimatedVisibilityScope.() -> Unit)
): Unit
Es reicht aus, den Inhalt innerhalb von AnimatedVisibility() per Lambda-Ausdruck zu definieren und zusätzlich die Bedingung festzulegen, unter der die Animation ausgeführt werden soll. Die Funktion selbst wendet dann die Standardanimation auf den Inhalt an.
Die Animation lässt sich außerdem sehr flexibel an die eigenen Anforderungen anpassen. In unserem Beispiel soll eine Nachricht aus der TopAppBar eingeblendet werden, wenn auf das Symbol zum Hinzufügen oder Entfernen eines Favoriten geklickt wird. Dafür erstellen wir eine Composable-Funktion ShowMessage(), die das einblendbare Panel enthält und den Zustand favoriteMessageShown sowie isFavorite entgegennimmt. Da favoriteMessageShown nach einer gewissen Zeit wieder auf false gesetzt werden soll, definieren wir:
suspend fun showFavoriteStatusMessage() {
if (!favoriteMessageShown) {
favoriteMessageShown = true
delay(2000L)
favoriteMessageShown = false
}
}
AnimatedVisibility() besitzt außerdem zwei Argumente zur Anpassung der Animation: EnterTransition und ExitTransition. Es gibt viele Funktionen, mit denen sich das Ein- und Ausblenden konfigurieren lässt. Die vollständige Liste findest du in der Jetpack Compose Animation documentation. Wir verwenden hier slideInVertically() und slideOutVertically(). In den Parametern legen wir den Startpunkt des Offsets sowie Typ und Dauer der Animation fest. Zusätzlich können EnterTransition- oder ExitTransition-Funktionen kombiniert werden, indem man sie einfach addiert - in diesem Beispiel mit fadeIn() beziehungsweise fadeOut().
Ihnen gefällt, wie wir die Dinge angehen?
Dieser Blog soll Ihnen einen kleinen Einblick in unseren Alltag geben, wenn wir eine App in einer Full-Service-Umgebung entwickeln oder unsere Expertise gezielt als EaaS einbringen.
Es gibt verschiedene Animations-Modifikatoren (animateContentSize(), animateItemPlacement(), animateEnterExit()), die sich besonders gut auf Listenelemente anwenden lassen. Schauen wir uns diese kurz an.
AnimateContentSize
Beim Drücken des Buttons wird der Inhalt der Karte mit einem leichten Bouncing-Effekt ein- beziehungsweise ausgeblendet.
AnimateItemPlacement
Dieser Modifikator erzeugt eine Animation, wenn sich die Position eines Elements ändert. Das kann zum Beispiel beim Löschen oder Umsortieren eines Eintrags in einer Liste eingesetzt werden.
AnimateEnterExit
Dieser Modifikator ist für die Animation eines Elements verantwortlich, wenn es den Bildschirm betritt oder verlässt.
Eine einfache Wertänderung animieren
Zusätzlich zu den fertigen Funktionen für Übergänge können in Compose auch konkrete Werte animiert werden, etwa mit animateColorAsState(), animateDpAsState(), animateFloatAsState() und ähnlichen APIs.
AnimateColorAsState
Angenommen, beim Klick auf einen Button, der die Beschreibung einer Box aufklappt, soll nicht nur die Größe des Containers animiert werden, sondern auch seine Farbe. Ohne Animation würde die Hintergrundfarbe so gesetzt werden:
val backgroundColor = if (detailEnabled)
MaterialTheme.colorScheme.tertiaryContainer
else MaterialTheme.colorScheme.primaryContainer
Damit die Farbänderung ebenfalls weich animiert wird, wenn sich detailEnabled ändert, kapseln wir diese Logik in animateColorAsState() und konfigurieren bei Bedarf zusätzliche Animationsparameter.
AnimateDpAsState
Mit dp-Werten werden in Compose typischerweise Größen, Abstände oder Padding definiert. Wenn wir eine Änderung dieser Werte animieren wollen, kapseln wir den entsprechenden Wert in animateDpAsState().
AnimateFloatAsState
Mit einem Float-Wert kann zum Beispiel der Rotationswinkel eines Symbols definiert werden. Wenn wir den bedingten Ausdruck in animateFloatAsState() kapseln, erhalten wir eine schöne Animation dafür, wie sich das Symbol beim Anzeigen der Box-Details dreht.
Wenn Sie es bis hier geschafft haben, gehen wir davon aus, dass Sie ein gewisses Interesse an unserer Arbeit gewonnen haben. Das freut uns. Geben Sie uns gerne Feedback oder sprechen Sie mit uns über Ihr Projekt.
Wir haben hier die grundlegenden Animationswerkzeuge betrachtet, die Jetpack Compose bereitstellt. Wie man sieht, ist der Einsatz von Animationen deutlich einfacher geworden und die Möglichkeiten sind vielfältiger als früher.
Durch die Kombination unterschiedlicher Animationstools und etwas Kreativität lassen sich sehr ansprechende Ergebnisse erzielen.
Zum Abschluss bleibt festzuhalten, dass Nutzeraktionen, die von sinnvollen Animationen begleitet werden, dabei helfen, sich in einer Benutzeroberfläche besser zurechtzufinden. Animationen machen Zustände der UI sichtbar, lenken Aufmerksamkeit und helfen Nutzern dabei, die Auswirkungen ihrer Aktionen besser zu verstehen.
Den Quellcode findest du in unserem öffentlichen GitHub-Repository: Cayas Github.
FAQ
Jetpack Compose bietet mehrere Animations-APIs, darunter AnimatedVisibility für Ein- und Ausblendungen, Animations-Modifikatoren wie animateContentSize sowie animate*AsState-Funktionen für einfache Wertänderungen. Der deklarative Ansatz erleichtert das Erstellen und Lesen von Animationen.
AnimatedVisibility ist eine Composable-Funktion, die das Erscheinen und Verschwinden von Inhalten animiert. Sie übergeben einen sichtbaren Boolean-Wert und optional Enter- und Exit-Transitionen, und Compose wendet standardmäßig geeignete Animationen auf den Inhalt an.
Verwenden Sie den Modifikator animateContentSize, um Größenänderungen beim Ein- oder Ausklappen von Inhalten weich zu animieren. Für Positionsänderungen in Listen können Sie animateItemPlacement in LazyColumn- oder LazyRow-Elementen einsetzen.
Halten Sie Animationen dezent und zielgerichtet, damit sie die Benutzererfahrung verbessern, ohne abzulenken. Verwenden Sie AnimatedVisibility für Sichtbarkeitswechsel, animateContentSize für Layout-Übergänge und animate*AsState für einfache Wertanimationen. Wählen Sie die passende API je nach Art der Änderung.
Wenden Sie den Modifikator animateItemPlacement auf Elemente innerhalb einer LazyColumn oder LazyRow an. Wenn sich die Reihenfolge der Listendaten ändert, animiert Compose die Elemente sanft an ihre neue Position.
Igor Gridin
Mit über 15 Jahren Erfahrung in der Softwareentwicklung mit Java und Kotlin unterstütze ich im Banken- und Logistik-Bereich unsere Kunden bei spannenden nativen Android-Projekten. Hier schreibe ich über alle neuen Technologien und Trends, die im Bereich der Android-Anwendungsentwicklung auftauchen.
Spracheingabe macht es möglich, gegessene und getrunkene Lebensmittel intuitiv zu erfassen, ohne ständig auf ein Gerät schauen oder tippen zu müssen. Statt alles mühsam per Hand einzugeben, können Nutzer Mahlzeiten und Snacks einfach per Sprache dokumentieren. Das spart Zeit und senkt die Hürde für eine regelmäßige Erfassung.
Fast zwei Jahre nach der stabilen Veröffentlichung von Jetpack Compose sind viele Entwickler noch immer skeptisch, ob sich das Framework für eigene Projekte lohnt. Um diese Frage zu beantworten, vergleichen wir Android Views und Jetpack Compose anhand typischer Aufgaben in nativen Android-Projekten.
Erfahre, warum dein Xamarin.Android-Build mit "Error executing task Aapt: VersionCode is outside 0, 65535 interval" fehlschlägt und wie du dieses Problem umgehen kannst.