Flutter, Image - Button Widget
In diesem Beitrag möchte ich gerne erläutern wie man ein Image Button Widget für Flutter in Dart schreibt, das zwischen gedrückten - und normalen Zustand faded.
Ich bin der "digitalen Bilderrahmen - Blog - Post - Serie" natürlich etwas voraus und dabei parallel die App zu programmieren. Dabei habe ich mich gegen React Native und für Flutter entschieden. Flutter ist ein Software Development Kit für die Entwicklung von Apps für iOS, Android und dem Web, das auf der Programmiersprache Dart aufsetzt. Dabei ist es in Sachen Performance React Native überlegen. Dart möchte sich als eine Alternative zu JavaScript sehen und versucht dabei, nach Ansicht der Entwickler, einige grundsätzliche Probleme von JavaScript zu lösen. Es lässt sich nach JavaScript transpilen und läuft so im Browser. Zudem lässt sich Dart - Code auch mittels VM auf Android, iOS, Windows und Linux ausführen. Ein kompilieren in Ausführbare Binärdateien ist vorab auch möglich.
Fading Image Button
Das Widget soll sich verhalten wie ein Button und beim Drücken von einen Bild in ein anderes faden. Demnach braucht es einen Zustand, welche von der StatefulWidget Klasse geerbt werden kann.
Bisher definiert die Klasse nur ein paar Eigenschaften und die createState()
Methode. Der Hauptteil spielt sich auch in der _FadingImageButtonState
Klasse ab.
Der "_" im Namen von Membern definiert diese als private und sind so vor dem Zugriff von außerhalb der Library geschützt.
Benannte Parameter
Parameter in geschweiften Klammern sind benannte Parameter.
void func( {@required int a, int b, String c} ) { /* ... */ }
Benötigte benannte Parameter erhalten den Zusatz @required
. Hier wird a
benötigt. Der Aufruf wäre wie folgt: func(a: 1, b: 2, c: "Drei");
Optionale Parameter
Optionale Parameter werden in eckigen Klammern angegeben.
void func(int a, [int b], [String c]) { /* ... */ }
Hier sind b
und c
optional.
Nicht übergebene benannte oder optionale Parameter sind null
.
Button State
Im gedrückten Zustand soll Bild 1 zu Bild 2 faden. Für diesen Effekt legen wir beide Bilder übereinander und setzen im Normalzustand die Opazität von Bild 2 auf 0. Beim Drücken wird dann die Opazität auf 1 gesetzt. Das AnimatedOpacity
Widget macht das Animieren nicht mehr zu unseren Problem.
Die Methode initState
initialisiert opacity
mit 0,0 und didChangeDependencies
werden die beiden Bilder gecached damit es nicht zu einem etwaigen Nachladen kommt.
Die build
Methode erstellt auf Flutters Anweisung hin unser Widget und ist die letzte, die wir benötigen.
Zunächst weisen wir allen optionalen Eigenschaften, die nicht übergeben wurden, einen Standardwert zu.
double width = widget.width ?? 128
Der ??
Operator überprüft die Variable auf null
. Ist sie null
dann wird der angegebene Wert und wenn nicht dann der Variablenwert zugewiesen.
Als Basis dient uns ein GestureDetector
Widget in dem die Image
Widgets in einem Stack
Widget übereinander gelegt werden. Das AnimatedOpacity
Widget handled die Animation der Opazität.
In den onTap...
Eigenschaften des GestureDetector
Widgets lassen wir den Zustand von opacity
ändern. Die Methode setState
triggered dabei das Neurendern des Widgets. Beim schlichten setzen auf z.B. opacity = 1
hat Flutter keine Ahnung das sich der Wert geändert hat.
Damit bei einem eher schnellen Drücken auch die Animation abgespielt werden kann wird die onPressed
Funktion etwas zeitverzögert ausgeführt. Die Verzögerung beträgt die Hälfte von duration
.
Es ist kein Zufall das in den letzten drei Absätzen das Wort "Widget" ziemlich oft vorkam. In Flutter ist alles ein Widget.
Das Widget nutzen
Widget build(BuildContext context) {
return FadingImageButton(
onPressed: () => print(pressed),
image: Image.asset("assets/button.png"),
onPressedImage: Image.asset("assets/button-pressed.png"),
);
}