Wer eine eigene App pro­gram­mie­ren möchte, hat dafür zahl­rei­che Optionen. Baukästen mit ein­satz­fer­ti­gen App-Kom­po­nen­ten erfreuen sich aufgrund ihrer einfachen Nutz­bar­keit großer Be­liebt­heit, doch auch Frame­works zeichnen sich zunehmend dadurch aus, den Ent­wick­lungs­pro­zess für Nutzer so einfach wie möglich zu gestalten. Einer der mo­derns­ten Vertreter ist das von Google ent­wi­ckel­te Software De­ve­lo­p­ment Kit (SDK) Flutter. Das quell­of­fe­ne Framework er­mög­licht die Ent­wick­lung hoch per­for­man­ter Mobile Apps (für iOS und Android) sowie von Web- und Desk­top­an­wen­dun­gen in der Google-Sprache Dart.

In unserem Flutter-Tutorial stellen wir Ihnen die wich­tigs­ten Schritte zum Einstieg in die Google-SDK vor.

Flutter lernen: Das sind die Vor­aus­set­zun­gen

Wer das Pro­gram­mie­ren mit Flutter lernen möchte, benötigt nicht zwingend Vorwissen in Sachen App- und Web­ent­wick­lung. Auch die bereits genannte Google-Sprache Dart kann Ihnen prin­zi­pi­ell noch gänzlich fremd sein. Falls Sie mit ob­jekt­ori­en­tier­tem Code und grund­le­gen­den Pro­gram­mier­kon­zep­ten wie Variablen, Schleifen und Be­din­gun­gen vertraut sind, sind Sie bereits gut für die Arbeit mit dem Framework gerüstet.

In diesem Flutter-Tutorial wollen wir einen ersten Blick auf die Ent­wick­lung mit dem Software-De­ve­lo­p­ment-Kit werfen und zu diesem Zweck eine einfache App schreiben, die nach zu­fäl­li­gem Muster Wörter kom­bi­niert und diese Kom­bi­na­tio­nen im Anschluss prä­sen­tiert. Hierfür benötigen Sie die Basis-Werkzeuge für die Pro­gram­mie­rung mit Flutter: Das Flutter-SDK und einen Editor. Erst­ge­nann­tes ist für Windows, macOS und Linux verfügbar – das jeweilige In­stal­la­ti­ons­pa­ket können Sie direkt über die of­fi­zi­el­le Flutter-Website her­un­ter­la­den.

In puncto Editor haben Sie im Prinzip die freie Auswahl. Für eine optimale User-Ex­pe­ri­ence mit au­to­ma­ti­scher Code-Ver­voll­stän­di­gung, Syn­tax­her­vor­he­bung sowie Un­ter­stüt­zung bei Debugging und der Be­ar­bei­tung von Widgets empfiehlt Google aber die Nutzung eines Code-Editors für den der Groß­kon­zern auch ein of­fi­zi­el­les Flutter-Plugin anbietet: In unserem Flutter-Tutorial nutzen wir aus diesem Grund Android Studio. Nach der In­stal­la­ti­on dieser für die Android-App-Ent­wick­lung op­ti­mier­ten Ent­wick­lungs­um­ge­bung richten Sie das Flutter-Plugin fol­gen­der­ma­ßen ein:

  1. Rufen Sie den Menüpunkt „File“ auf.
  2. Klicken Sie auf „Settings“ und wählen Sie danach die Rubrik „Plugins“ aus.
  3. Tippen Sie „Dart“ in die Suchzeile ein und klicken Sie beim gleich­na­mi­gen vor­ge­schla­ge­nen Ergebnis auf den „Install“-Button, um zunächst die Er­wei­te­rung für die er­for­der­li­che Pro­gram­mier­spra­che Dart zu in­stal­lie­ren.
  4. Be­stä­ti­gen Sie die Nutzung der Third-Party-Er­wei­te­rung via „Accept“.
  5. Wie­der­ho­len Sie den Vorgang für den Such­be­griff „Flutter“ und drücken Sie nach er­folg­rei­cher In­stal­la­ti­on auf „Restart IDE“, um die Än­de­run­gen zu über­neh­men.
Hinweis

Als Al­ter­na­ti­ve zu Android Studio schlägt Google die Ver­wen­dung von GNU Emacs, Visual Studio Code und IntelliJ IDEA vor – An­wen­dun­gen, für die es ebenfalls ein of­fi­zi­el­les Flutter-Plugin gibt.

Schritt 1: Die erste eigene Flutter-App erstellen

Sobald Sie Flutter und die ge­wünsch­te Ent­wick­lungs­um­ge­bung (bzw. den Editor) in­stal­liert haben, können Sie Ihre erste Flutter-Anwendung kreieren. Wie bereits erwähnt verwenden wir in diesem Flutter-Tutorial Android Studio, weshalb wir die IDE nun zu diesem Zweck starten. Über das Menü „File“ wählen Sie im ersten Schritt die Punkte „New“ und an­schlie­ßend „New Flutter Project“ aus, um ein neues Projekt auf Basis des App-Frame­works zu starten.

Wählen Sie „Flutter Ap­pli­ca­ti­on“ als ge­wünsch­ten Pro­jekt­typ aus und drücken Sie auf „Next“. Im Kon­fi­gu­ra­ti­ons­me­nü de­fi­nie­ren Sie nun einen Ar­beits­ti­tel und den lokalen Spei­cher­ort für Ihre Anwendung. Optional können Sie auch eine Be­schrei­bung des Projekts hin­zu­fü­gen. In der Zeile „Flutter SDK path“ geben Sie den Pfad zum in­stal­lier­ten Flutter-Framework an.

Klicken Sie zum Abschluss auf „Finish“, damit die neue Flutter-App erstellt wird. In die Datei main.dart, die grund­le­gen­de Ar­beits­da­tei eines Projekts sowie dieses Flutter-Tutorials, fügen Sie nun folgenden Code ein, um die App eine einfache „Hello World“-Nachricht prä­sen­tie­ren zu lassen (bereits vor­han­de­nen Code in der main.dart-Datei können Sie löschen):

// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
	@override
	Widget build(BuildContext context) {
		return MaterialApp(
			title: 'Welcome to Flutter',
			home: Scaffold(
				appBar: AppBar(
					title: Text('Welcome to Flutter'),
				),
				body: Center(
					child: Text('Hello World'),
				),
			),
		);
	  }
}

Sobald Sie das Snippet eingefügt haben, können Sie sich diese erste Version Ihrer eigenen App prä­sen­tie­ren lassen. In Android Studio wählen Sie hierfür die jeweilige virtuelle Maschine aus (unter „Flutter Device Selection“) und drücken an­schlie­ßend auf den Abspiel-Button („Run main.dart“):

Hinweis

Für die Vorschau einer App in Android Studio muss ein Image der ge­wünsch­ten Ziel­platt­form in­stal­liert sein. An­dern­falls können Sie unter „Flutter Device Selection“ kein vir­tu­el­les Testgerät für den Test der App auswählen. Zum Hin­zu­fü­gen wählen Sie die Me­nü­punk­te „Tools“ und „AVD Manager“ aus. An­schlie­ßend drücken Sie auf „Create Virtual Device“ und in­stal­lie­ren das virtuelle Gerät Ihrer Wahl. Eine aus­führ­li­che Anleitung zum Erstellen und Verwalten vir­tu­el­ler Geräte in Android Studio finden Sie im Android-Developer-Forum.

Der erste Start bzw. das Debugging der App wird einige Zeit in Anspruch nehmen – Sie müssen sich also ein wenig gedulden, bevor Sie die Will­kom­mens­nach­richt auf dem Bild­schirm Ihrer Test­um­ge­bung sehen.

Schritt 2: Ein externes Paket einbinden

Nachdem wir im ersten Schritt des Flutter-Tutorials eine erste einfache App zum Laufen gebracht haben, soll diese nun um ein externes Paket erweitert werden. Genauer gesagt wollen wir nun das für unser Pro­jekt­ziel – eine App, die Wörter nach einem zu­fäl­li­gen Muster mit­ein­an­der kom­bi­niert – er­for­der­li­che Wör­ter­pa­ket einbinden. Ex­em­pla­risch nutzen wir das Open-Source-Paket „english_words“ (MIT-Lizenz), das Sie wie viele andere quell­of­fe­ne Pakete auf der Plattform pub.dev finden. Das Modul enthält die über 5000 gän­gigs­ten eng­li­schen Wörter, weshalb es optimal für die Zwecke dieses Flutter-Tutorials geeignet ist.

Für das Ma­nage­ment von Paketen und Ab­hän­gig­kei­ten nutzen Flutter-Apps die Datei pubspec.yaml. Rufen Sie diese Datei auf und fügen der Liste der Ab­hän­gig­kei­ten einen Eintrag für das Sprach­pa­ket (auf aktuelle Version achten; hier: 3.1.5) hinzu:

dependencies:
	flutter:
		sdk: flutter
	cupertino_icons: ^0.1.2
english_words: ^3.1.5

An­schlie­ßend führen Sie den Befehl „flutter pub get“ aus. Android Studio hat hierfür sogar direkt eine Schalt­flä­che mit dem Namen „Pub get“ parat.

Wechseln Sie zurück zur Haupt-Ar­beits­da­tei main.dart und im­por­tie­ren Sie dort das Sprach­pa­ket:

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

Zudem fügen Sie im Code der App die folgende Zeile hinzu:

final wordPair = WordPair.random();

Zum Abschluss ersetzen Sie den child-Eintrag, der für die Ausgabe des Textes „Hello World“ sorgt durch folgenden Eintrag:

child: Text(wordPair.asPascalCase),

Mit jeder Aus­füh­rung dieses neuen, aktuellen App-Codes erhalten Sie nun ein zufällig ge­ne­rier­tes Paar eng­li­scher Wörter.

Schritt 3: Ein zu­stands­be­haf­te­tes Widget hin­zu­fü­gen

Zu­stands­lo­se Widgets (Stateless Widgets), wie bisher in diesem Google-Flutter-Tutorial genutzt, sind un­ver­än­der­lich. Während der Laufzeit einer App können sie ihren Status nicht ändern, weshalb sich diese Art von Widgets nicht um­schrei­ben lässt, während die Anwendung aus­ge­führt wird. Zu­stands­be­haf­te­te Widgets (auch Stateful Widgets) können ihren Status hingegen auch während der App-Laufzeit verändern, sodass dieser nicht bereits mit der Aus­füh­rung fest­ste­hen muss. Möchten Sie be­stimm­ten Elementen Ihrer Flutter-App also In­ter­ak­ti­vi­tät verleihen, benötigen Sie Stateful Widgets.

Hinweis

Widgets sind in Flutter immer entweder zu­stands­los oder zu­stands­be­haf­tet. Typische Beispiele für zu­stands­lo­se Kom­po­nen­ten sind Icons, Buttons oder Text-Bausteine. Typische Beispiele für einfache zu­stands­be­haf­te­te Widgets sind Check­bo­xen, Formulare oder Schie­be­reg­ler.

Auch unsere Beispiel-App soll an dieser Stelle ein in­ter­ak­ti­ves Widget erhalten. Für die Im­ple­men­tie­rung sind min­des­tens zwei Klassen er­for­der­lich: Eine Sta­teful­Wid­get-Klasse, die ih­rer­seits wiederum eine Instanz der State-Klasse generiert.

Zu Beginn erstellen wir eine mi­ni­ma­lis­ti­sche State-Klasse namens „Ran­dom­Words­Sta­te“, indem wir folgenden Code an das Ende der main.dart einfügen:

class RandomWordsState extends State<randomwords> {</randomwords>
	// TODO Add build() method
}

Die ge­ne­ri­sche State-Klasse wird in diesem Fall explizit für die Nutzung mit dem Widget „Ran­dom­Words“ zu­ge­wie­sen. Das Stateful Widget selbst wird im nächsten Schritt durch folgenden Input in die main.dart-Datei ge­schrie­ben (im Code: vor der Klasse „Ran­dom­Words­Sta­te“):

class RandomWords extends StatefulWidget {
	@override
	RandomWordsState createState() => RandomWordsState();
}

Führen Sie diesen neuen App-Code aus, liefert Flutter Ihnen den Hinweis, dass aktuell noch keine build()-Funktion für „Ran­dom­Words­Sta­te“ definiert ist.

Im ein­ge­füg­ten Snippet der State-Klasse befindet sich an der ent­schei­den­den Stelle noch der Platz­hal­ter-Kommentar „//TODO Add build() method“, der nun durch den Code für die Build()-Funktion ersetzt wird:

class RandomWordsState extends State<randomwords> {</randomwords>
	@override
	Widget build(BuildContext context) {
		final wordPair = WordPair.random();
		return Text(wordPair.asPascalCase);
	}
}

Zuletzt entfernen Sie die Zeile „final wordPair = WordPair.random();“ aus der MyApp-Klasse und ersetzen den Child-Eintrag „child: Text(wordPair.asPas­cal­Ca­se),“ durch „child: Ran­dom­Words(),“.

Führen Sie diesen neuen Code nun aus, sollte das virtuelle Testgerät wie zuvor ein Wortpaar aus­spie­len – nun al­ler­dings auf Basis eines zu­stands­be­haf­te­ten Widgets, das po­ten­zi­ell auch eine In­ter­ak­ti­on der zu­grei­fen­den Nutzer er­mög­licht.

Schritt 4: Eine endlos scroll­ba­re Lis­ten­an­sicht erstellen

Um ein erstes Beispiel für ein in­ter­ak­ti­ves Flutter-Widget zu liefern, soll unsere App im letzten Teil dieses Google-Flutter-Tutorials noch etwas erweitert werden: Genauer gesagt soll die „Ran­dom­Words­Sta­te“-Klasse da­hin­ge­hend angepasst werden, dass sie nicht mehr nur einzelne Wortpaare, sondern eine endlose Liste mit Wort­paa­ren prä­sen­tiert, durch die der Nutzer scrollen kann. Zudem sollen bereits vor­ge­schla­ge­ne Wortpaare ge­spei­chert (um doppelte Einträge zu vermeiden) und die Schrift­grö­ße der Er­geb­nis­se ver­grö­ßert werden.

Beginnen Sie mit den beiden zuletzt genannten Punkten (Spei­che­rung der prä­sen­tier­ten Er­geb­nis­se und Font-Anpassung), indem Sie eine _sug­ges­ti­ons-Liste und eine _big­ger­Font-Variable einbinden:

class RandomWordsState extends State<randomwords> {</randomwords>
	final _suggestions = <wordpair>[];</wordpair>
	final _biggerFont = const TextStyle(fontSize: 18.0);
}

Im Anschluss fügen Sie – ebenfalls in die „Ran­dom­Words­Sta­te“-Klasse die passende _build­Sug­ges­ti­ons()-Funktion ein:

Widget _buildSuggestions() {
	return ListView.builder(
		padding: const EdgeInsets.all(16.0),
		itemBuilder: (context, i) {
			if (i.isOdd) return Divider();
			final index = i ~/ 2;
			if (index >= _suggestions.length) {
			_suggestions.addAll(generateWordPairs().take(10));
			}
			return _buildRow(_suggestions[index]);
		});
}

Die auf­ge­zeig­te Funktion erweitert die App um gleich mehrere Ei­gen­schaf­ten: Unter anderem wird die Auf­lis­tung der Wortpaare (List.View) in­te­griert, die zudem durch eine Ein-Pixel-Trenn­li­nie (Divider) über­sicht­li­cher gemacht wird. Zudem ist definiert, dass weitere zehn Vor­schlä­ge geliefert werden (Zeile: _sug­ges­ti­ons.addAll), sobald der Nutzer an das Ende der aktuell prä­sen­tier­ten Liste gelangt ist.

Ele­men­ta­rer Be­stand­teil des er­wei­ter­ten Widgets ist außerdem die Funktion _buildRow(), die einmal pro Wortpaar auf­ge­ru­fen wird und die Paare als ListTitle prä­sen­tiert. Diese Funktion im­ple­men­tie­ren wir daher gleich im nächsten Schritt:

Widget _buildRow(WordPair pair) {
	return ListTile(
		title: Text(
			pair.asPascalCase,
			style: _biggerFont,
		),
	);
}

Die build()-Methode, die wir bei der Ge­ne­rie­rung des zu­stands­be­haf­te­ten Widgets (Schritt 3) im­ple­men­tiert haben, muss nun noch an­ge­wie­sen werden, die Funktion build­Sug­ges­ti­ons() zu verwenden. Der bisherige Inhalt der Methode ist daher durch folgenden Code aus­zu­tau­schen:

@override
Widget build(BuildContext context) {
	return Scaffold(
		appBar: AppBar(
			title: Text('Word Generator'),
		),
		body: _buildSuggestions(),
	);
}

Zuletzt ak­tua­li­sie­ren Sie die build()-Methode auch in der MyApp-Klasse, indem Sie den Title ändern und im Home-Eintrag de­fi­nie­ren, dass es sich um ein Ran­dom­Words-Widget handelt:

title: 'Word Generator',
home: RandomWords(),

Führen Sie den Code nun erneut aus, läuft die App unter dem neuen Ti­tel­na­men „Word Generator“. Zudem wird gleich eine ganze Auf­lis­tung von Wort­kom­bi­na­tio­nen prä­sen­tiert und per Scrollen können Sie weitere Er­geb­nis­se anzeigen lassen.

Flutter-Tutorial: Zu­sam­men­fas­sung

Im Rahmen des vor­an­ge­gan­ge­nen Google-Flutter-Tutorials haben Sie die wich­tigs­ten Grund­la­gen für die Arbeit mit Flutter gelernt und konnten Sie in einer einfachen Beispiel-App anwenden. Natürlich können Sie Ihre in­di­vi­du­el­len Flutter-An­wen­dun­gen noch deutlich de­tail­lier­ter und um­fang­rei­cher ent­wi­ckeln. Auch das Design können Sie in­di­vi­du­ell gestalten, wenn Sie sich erst einmal in­ten­si­ver mit dem Framework aus­ein­an­der­ge­setzt haben.

Ab­schlie­ßend prä­sen­tie­ren wir nun noch einmal den kom­plet­ten Code der ent­wi­ckel­ten Beispiel-App für Android in der main.dart-Datei:

import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
	@override
	Widget build(BuildContext context) {
		return MaterialApp(
			title: 'Word Generator',
			home: RandomWords(),
		);
	}
}
class RandomWords extends StatefulWidget {
	@override
	RandomWordsState createState() => RandomWordsState();
}
class RandomWordsState extends State<randomwords> {</randomwords>
	final _suggestions = <wordpair>[];</wordpair>
	final _biggerFont = const TextStyle(fontSize: 18.0);
	@override
	Widget build(BuildContext context) {
		return Scaffold(
			appBar: AppBar(
				title: Text('Word Generator'),
			),
			body: _buildSuggestions(),
		);
}
Widget _buildSuggestions() {
		return ListView.builder(
			padding: const EdgeInsets.all(16.0),
			itemBuilder: (context, i) {
				if (i.isOdd) return Divider();
				final index = i ~/ 2;
				if (index >= _suggestions.length) {
				_suggestions.addAll(generateWordPairs().take(10));
				}
				return _buildRow(_suggestions[index]);
			});
}
Widget _buildRow(WordPair pair) {
		return ListTile(
			title: Text(
				pair.asPascalCase,
				style: _biggerFont,
			),
		);
	}
}
Zum Hauptmenü