• Noser.com
facebook
linkedin
twitter
youtube
  • NOSERmobile
    • Android
    • HTML 5
    • Hybrid Apps
    • iOS
    • Windows Phone
  • NOSERembedded
    • Medizintechnik
  • NOSERprojektmanagement
  • NOSERtesting
  • NOSERlifecycle
    • .NET Allgemein
    • Application Lifecylce Management
    • Apps
    • Architektur
    • ASP.NET
    • Azure
    • Cleancode
    • Cloud
    • Silverlight
    • Visual Studio / Team Foundation Server
    • Windows 8
    • Windows Presentation Foundation
  • NOSERinnovation
    • Big Data
    • Cloud
    • IoT
    • Operations Research
    • Augmented Reality
    • RFID, NFC, Bluetooth LE

Shared Element Transition unter Android umsetzen

09. Juli 2018
Rehmann Christoph
0
android, animation, UX

Animationen sind ein wichtiges Mittel um die Ausdrucksstärke eines User Interfaces zu erhöhen. Sinnvoll eingesetzt lassen sich damit nicht nur Wartezeiten beim Laden von Inhalten überbrücken, sondern auch Informationen vermitteln. Eine in Apps oft eingesetzte Animation ist die sogenannte Shared Element Transition. Mit ihr werden räumliche oder hierarchische Zusammenhänge zwischen Elementen vermittelt und eine kontinuierliche User Experience ermöglicht.

In folgendem Beispiel möchte ich zeigen, wie man in wenigen Schritten eine Shared Element Transition unter Android implementiert. Die Animation wird in diesem Beispiel eingesetzt um von der Hauptansicht (Listenansicht) zu einer Detailansicht zu wechseln. Das fertige Resultat sieht wie folgt aus:

Beispiel der Shared Element Transition

Shared Element Transition

Der komplette Code samt Beispiel App kann hier gefunden werden.

Shared Element Transition – Walkthrough

Ab Android 5 kann man Shared Element Transitions bereits in wenigen Schritten implementieren:

Window Content Transitions aktivieren

Als erstes muss man Content Transitions im Application Theme aktivieren. Dazu setzt man folgendes Flag:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
	<item name="android:windowContentTransitions">true</item>
</style>

Transition Name festlegen

Shared Element Transitions können zwischen Fragments aber auch zwischen Activites stattfinden. In diesem Beispiel verwende ich zwei Activities mit eigenen Layouts. Das zu animierende Element muss in beiden Layouts den gleichen Transition Name besitzen. Diesen kann man entweder direkt im XML festlegen oder im Code per setTransitionName setzen. Da die Listenansicht eine vielzahl von dynamischen Elementen enthalten kann, konnte ich den Transition Name nicht statisch im XML setzten. Stattdessen habe die Implementierung innerhalb des Viewholders verwendet:

class ViewHolder(private val containerView: View, private val itemClick: (Monkey, ImageView) -> Unit)
        : RecyclerView.ViewHolder(containerView) {

        fun bind(monkey: Monkey) {
            with(monkey) {
                Picasso.get()
                        .load(monkey.imageUrl)
                        .placeholder(R.drawable.placeholder)
                        .into(containerView.imageView)
                containerView.textView_name.text = name
                containerView.setOnClickListener { itemClick(this, containerView.imageView) }
                containerView.imageView.transitionName = name
            }
        }
}

Einfachheitshalber habe ich es so gelöst, dass der Transition Name einer Item-View jeweils dem Namen des Objektes (in diesem Fall Affen) entspricht.

Activity starten

Als nächstes muss man nun die Detail-Activity starten. Dabei muss zusätzlich auch ein Bundle mitgegeben werden, welches die Optionen der Scene Transition enthält.

val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, imageView, monkey.name)
startActivity(MonkeyDetailActivity.newIntent(this, monkey), options.toBundle())

Da ich keinen statischen Transition Name verwendet habe, musste ich zusätzlich noch sicherstellen, dass auch auf der Detail-Activity der korrekte Transition Name gesetzt wird.

Weitere Optionen

Man hat man auch die Möglichkeit mehrere Elemente auf einmal zu animieren. Allerdings sollte man aufpassen, dass die Animation nicht zu überladen wirkt. Weiter kann man auch die Art der Animation beim hin- und zurücknavigieren anpassen. Dabei kann man eigene Transitions erstellen oder bereits bestehende verwenden (z.B. explode, slide, fade).

Fazit

Meiner Meinung nach sind Animationen ein wichtiger Bestandteil von modernen Apps und sie können einen wichtigen Beitrag zur User Experience leisten. Android liefert viele Mittel um Animationen schnell und einfach zu implementieren. Allerdings soll hier auch angemerkt sein, dass dieses Beispiel eher simpel gehalten wurde und durchaus auch komplexere und aufwendigere Implementationen möglich sind. Besonders im Fine-Tuning kann der Aufwand wieder ansteigen. Google liefert hierzu aber umfangreiche Beispiele und Erklärungen. Ebenso geben auch die Material Design Guidelines einen guten Einstieg in das Thema und zeigen Beispiele, wo man Animationen sinnvoll einsetzt.

Im Fall der Shared Element Transition ist ebenfalls zu beachten, dass diese erst ab Android 5 unterstützt werden.

Key-Frame Animationen mit ConstraintLayout & ConstraintSet erstellen

22. Mai 2018
Rehmann Christoph
1
ConstraintLayout, ConstraintSet, Key-Frame Animation, UX

Eine gute mobile App muss nicht nur zuverlässig funktionieren, sondern auch ein ansprechendes UI-Design und eine gute Benutzererfahrung bieten. Animationen können bei richtiger Verwendung dazu beitragen, die Aufmerksamkeit der Benutzer auf sich zu ziehen und die App von anderen abzuheben. Mit dem ConstraintLayout von Android lassen sich dabei auf sehr einfache Art und Weise kommplexe Animationen erstellen.

ConstraintLayout

Das ConstraintLayout wurde erstmals vor zwei Jahren von Google vorgestellt und hat seit rund einem Jahr die Beta-Phase hinter sich gelassen. Es ist vergleichbar mit dem RelativeLayout, bietet jedoch mehr Flexibilität. Damit lassen sich komplexe Layout Hierarchien in einer flachen Struktur abbilden. Dadurch wird die Zeit für das Rendern eines Layouts reduziert und eine bessere Performance erreicht.

Man kann es aber auch in Kombination mit ConstraintSet verwenden, um komplexe Animationen auf einfache Art und Weise umzusetzen. Die Grundidee ist, dass man ein Start-Layout und ein End-Layout (sogenannte Key-Frames) definiert. Anschliessend animiert der TransitionManager den Übergang vom ConstraintSet des Start-Layouts zum ConstraintSet des End-Layouts.

Das fertige Beispiel sieht wie folgt aus:

Vorschau der Animation

Walkthrough

Start-Layout erstellen

Als erstes erstellen wir das initiale Layout. Das Beispiel ist relativ simpel aufgebaut. Der Titel und Untertitel sind Links ausgerichtet und mit einem Margin von Oben versetzt. Der grösste Teil des Bildschirms wird von dem Bild eingenommen, welches oberhalb der Beschreibung platziert ist.

Start-LayoutZiel-Layout  erstellen

Beim Ziel-Layout sind die Texte ausgeblendet und das Bild nimmt den ganzen Platz ein. Der rechte Rand des Titels ist am linken Rand des Layouts ausgerichtet. Sprich wurde nach Links herausgeschoben. Die Beschreibung wurde ebenfalls nicht einfach ausgeblendet, sondern an den unteren Rand des Layouts ausgerichtet.

ConstraintSet erstellen

Nachdem wir nun beide Layouts erstellt haben, können wir das ConstraintSet für das Ziel-Layout erstellen. Dies kann mit nur zwei Zeilen Code gemacht werden:

val endConstraintSet = ConstraintSet()
endConstraintSet.clone(this, R.layout.activity_monkey_detail)

Das ConstraintSet beinhaltet lediglich die Constraints, Grössen und Margins des Layouts. Andere Attribute werden nicht beachtet und könnten demnach auch weggelassen und müssen somit nicht jeweils abgeglichen werden.

ConstraintSet auf Layout anwenden

Wollen wir die Animation nun ausführen, so müssen wir nur eine Transition mit dem TransitionManager starten und das ConstraintSet auf das Layout anwenden:

TransitionManager.beginDelayedTransition(constraintLayout)
endConstraintSet.applyTo(constraintLayout)

Mit diesen vier Zeilen Code haben wir bereits die ganze Animation implementiert.

Standardmässig wird die Animation linear interpoliert. Dies kann man jedoch sehr einfach anpassen, indem man einen anderen Interpolator verwendet. In meiner Demo-App habe ich z.B. FastOutSlowInInterpolator verwendet:

val transition = ChangeBounds()
transition.interpolator = FastOutSlowInInterpolator()
TransitionManager.beginDelayedTransition(constraintLayout, transition)

Zusammenfassung

Mit Hilfe von Key-Frame Animationen kann sehr einfach eine komplexe Animation implementieren. Man muss dazu nur das Start- und End-ConstraintSet definieren und lässt den TransitionManager die Arbeit machen. Bei einfacheren Animation muss man sich überlegen, ob man wirklich zwei Layouts anlegen will. Hier kann es allenfalls sinnvoller sein, die Animation im Code abzubilden.

1234567

Tag Cloud

.NET android ANgular Angular Js AngularJs Arduino ASP.Net automated testing Azure Big Data C# C++ Cloud continuous integration Elm Embedded gRPC Internet of Things IoT Java Javascript M2M OWASP Projektmanagement protobuf Python Raspberry Pi Reactive Programming REST Scrum Security Softwarequalität SPA Testen testing Testmanagement Teststrategie Visual Studio WebAPI windows windows phone 8 WPF Xamarin Xamarin.Android Xamarin.Forms

Archive

Current Posts

  • Lasttests mit NBomber
  • Kreative Interaktion mit Xamarin.Forms Touch-Actions
  • Angular vs. React: Ein pragmatischer Vergleich
  • Eine Alternative zu Azure Time Series Insights, bitte?
  • Focus on the Secure Storage service of Trusted Firmware (TFM)

Last Comments

  • Noser Blog Touch-Actions in Xamarin.Forms - Noser Blog bei Mach mehr aus Animationen in Xamarin.Forms mit SkiaSharp
  • Noser Blog Focus on the Secure Storage service of Trusted Firmware (TFM) - Noser Blog bei First run of the Trusted Firmware (TFM) application
  • Noser Blog First run of the Trusted Firmware (TFM) application - Noser Blog bei Focus on the Secure Storage service of Trusted Firmware (TFM)
  • Noser Blog Focus on the Secure Storage service of Trusted Firmware (TFM) - Noser Blog bei Security management with Trusted Firmware
  • Noser Blog ZeroMQ / NetMQ mit Protocobuf - Noser Blog bei Tutorial: Protocol Buffers in ASP.NET Core

Popular Posts

Xamarin.Android Code Obfuscation

6 Comments

ManuScripts: Wenn jemand eine Reise tut... Funktionale Programmierung mit Elm - Teil 1 - Aufbruch

5 Comments

ManuScripts: Wenn jemand eine Reise tut... Funktionale Programmierung mit Elm - Teil 2 - Kein Picknick

4 Comments

Contact us

  1. Name *
    * Please enter your name
  2. Email *
    * Please enter a valid email address
  3. Message *
    * Please enter message
© 2013 NOSER ENGINEERING AG. All rights reserved. Datenschutz | Cookie-Richtlinie