Boehrsi.de - Blog

Flutter App Development - Teil 1 - Der Start

Erstellt am event Uhr von account_circle Boehrsi in label Development
Flutter App Development - Teil 1 - Der Start Bild

Wie man es im Leben kennt, hat alles wesentlich länger gedauert, sowohl die Planung für diese Newsreihe, wie auch die Entwicklung der App und die eigentliche Erstellung der Beiträge, doch heute geht es nun wirklich los.
Diese Tutorialreihe richte sich an Entwickler die bereits einige Erfahrungen sammeln konnten, bzw. die ein Grundverständnis für Dart open_in_new und Flutter open_in_new haben. Ich werde versuchen alles so umfangreich wie möglich zu erklären, allerdings werde ich nicht jeden Parameter eines jeden Widgets beschreiben. Dieses Tutorial soll vor allem auch Einblicke in Konzepte und Ideen geben, aber explizit kein Copy & Paste One-Page Tutorial sein. Geschriebener Code wird nach Möglichkeit gemäß den Effective Dart Style Guidelines open_in_new entwickelt.
Das gesamte Repository open_in_new ist im finalen Zustand bereits auf GitHub hinterlegt. Im Laufe der Tutorialreihe haben sich einige interne Strukturen und Bezeichnungen geändert, dies wird in den jeweiligen Beiträgen erläutert.
Ein neues Flutter Projekt startet immer mit einem kleinen Counter-App Beispiel. Dieses soll vor allem komplett neuen Entwicklern etwas Arbeit abnehmen und eine grundlegende Idee von Strukturen und dem Aufbau einer Flutter App vermitteln. Generell eine gute Idee, für uns nicht wirklich hilfreich, also räumen wir erstmal auf.
Ich werde, aufgrund meines Android Hintergrunds und weil es eines der wenigen Designkonzepte ist die selbst ich wirklich nachvollziehen kann, auf Material Design open_in_new setzen. In Flutter nutze ich entsprechend eine MaterialApp open_in_new.
Zudem werde ich in der App keine Übersetzungslogik einbauen und sie nur auf Englisch anbieten. Allerdings möchte ich explizit darauf hinweisen, dass ihr Apps, welche jemals produktiv genutzt werden sollen, von Anfang an lokalisiert entwickeln solltet. Zu diesem Thema findet ihr hier im Blog bald mehr. Dies gesagt möchte ich von jeglicher Form von Magic-Strings abraten, egal ob für Text den der Nutzer sieht oder für interne Inhalte. Strings sollte immer konstant definiert werden, ansonsten beißt man sich früher oder später ins Hinterteil.
Doch nun zum eigentlich Code. Als erstes entferne ich erklärende Kommentare aus der pubspec.yaml open_in_new und lib/main.dart open_in_new, denn selbige brauchen wir nicht. Ich versuche übrigens bei jeder ersten Erwähnung einer Datei den gesamten relativen Projektpfad anzugeben und anschließend nutze ich nur noch den Dateinamen. Ich hoffe dies hilf euch beim Finden der jeweiligen Dateien, überfrachtet den Beitrag selbst aber nicht zu sehr.

Als nächstes entferne ich die Counter-App Beispiel Logik aus meiner main.dart open_in_new und bereite alles für unseren Code vor. Das Ergebnis sind drei Dateien und zwei Packages. Das constants open_in_new Package wird alle Dateien mit Konstanten beinhalten, z.B. Text für Nutzer, Definitionen von Abständen in der UI und alle weiteren Werte die ich verteilt über die App, aber fest definiert nutzen möchte. Derzeit beinhaltet es lediglich die lib/constants/strings_user_visible.dart open_in_new Datei, mit einigen Strings. Konstante Strings starten im Dart mit einem k, um ihre Herkunft bei der Nutzung entsprechend klar zu machen.

lib/constants/strings_user_visible.dart (Code auf GitHub open_in_new)

// App
const kAppTitle = "Fluttery Site Summaries";

// RSS feed list
const kScreenRssListTitle = "Subscribed feeds";

Das rss_list open_in_new Package (später feed_list Package) wird alle Komponenten beinhalten, die zur Übersicht der abonnierten RSS Feeds gehören. Hier wird man später auch neue RSS Feed hinzufügen können. Außerdem ist dies der erste Screen den man beim App Start sieht. Derzeit ist hier die lib/rss_list/rss_list.dart open_in_new Datei zu finden, welche ein StatefulWidget open_in_new beinhaltet und mit etwas Platzhalterlogik ausgestattet ist. Imports innerhalb des Pakets werden ohne den package Prefix durchgeführt. Dadurch trennt man externe und interne Imports klar voneinander. Das eigentliche Widget beinhaltet lediglich die nötige build Methode und zeichnet das Scaffold open_in_new, welches den Rahmen für die Inhalte schafft und erstellt darin eine AppBar open_in_new, sowie eine Platzhalterliste. Der ListView.builder open_in_new ist nebenbei zu bevorzugen wenn große oder sehr dynamische Listen benötigt werden. Bei wenigen Einträgen, die relativ statisch sind, kann der ListView open_in_new Konstruktor genutzt werden.

lib/rss_list/rss_list.dart (Code auf GitHub open_in_new)

import 'package:flutter/material.dart';

import '../constants/strings_user_visible.dart';

class RssList extends StatefulWidget {
  @override
  _RssListState createState() => _RssListState();
}

class _RssListState extends State<RssList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(kScreenRssListTitle)),
      body: ListView.builder(itemBuilder: (context, index) {
        return ListTile(
          title: Text("$index"), // TODO replace placeholder with actual logic
        );
      }),
    );
  }
}

Die main.dart open_in_new bleibt im lib open_in_new Ordner und ist nun wesentlich kleiner geworden. Abgesehen vom Entfernen der gesamten Counter-App Logik habe ich nur minimale Farbanpassungen am Theme vorgenommen und lade unser RssList Widget.

lib/main.dart (Code auf GitHub open_in_new)

import 'package:flutter/material.dart';

import 'constants/strings_user_visible.dart';
import 'rss_list/rss_list.dart';

void main() {
  runApp(FssApp());
}

class FssApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: kAppTitle,
      theme: ThemeData(
        primarySwatch: Colors.teal,
        accentColor: Colors.redAccent,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: RssList(),
    );
  }
}

Diese Anpassungen sorgen beim Ausführen dafür, dass die App nun einen Screen, ohne Actions und mit einer unendlichen Liste darstellt. Die gesetzte accentColor koloriert Buttons und z.B. unter Android den Overscroll Effekt in Listen, während die primarySwatch Farbe die AppBar und andere Hauptkomponenten anpasst. Der gesetzte Titel des Screens wird aus unserer strings_user_visible.dart open_in_new geladen und direkt, ohne Class-Prefix oder dergleichen, genutzt.
Ich habe versucht diesen Einstieg sehr feingranular zu beschreiben und hoffe der Anfang ist gemacht. Solltet ihr Fragen oder Anregungen haben nur her damit, denn auch für mich ist es das erste Mal eine App zu entwickeln und parallel Erklärungen dazu zu verfassen. Die nächsten Beiträge, vor allem wenn mehr Logik dazu kommt, werden Dinge genereller beschreiben und nicht mehr auf jede einzelne Zeile o.ä. eingehen.

Related Links
Kommentare  
Kommentar erstellen
Mit dem Abschicken des Kommentars erklären sie sich mit der in der Datenschutzerklärung dargelegten Datenerhebung für Kommentare einverstanden. Spam, unangebrachte Werbung und andere unerwünschte Inhalte werden entfernt. Das Abonnieren via E-Mail ist nur für E-Mail Adressen erlaubt die Sie rechtmäßig administrieren. Widerrechtliche Abonnements werden entfernt.