Floating Action Button und Snack Bar für Flutter

Snack Bar
In diesem Artikel befassen wir uns mit dem Floating Action Button und der Snack Bar !

Photo by Luis Cortes on Unsplash

Wenn Du deine ersten Schritte mit Flutter gemacht hast, bist Du eventuell schon auf diesen Button gestossen. Im Boiler Code eines jeden Flutter Projekts, das Du neu erstellst, wird er verwendet !

Die Snack Bar wiederum ist ein Standard Element moderner App's.  Sie erscheint unten auf dem Screen. Ein gutes Beispiel ist zum Beispiel die Gmail App. Wenn Du dort zum Beispiel eine E-Mail löschst, erscheint sie und Du könntest die Aktion rückgängig machen.


Code Basis

Um es einfach zu halten verwende ich den Code aus dem Listen Artikel:

import 'package:flutter/material.dart';

List meineListe = [
  'Riad',
  'Zürich',
  'Hamburg',
  'London',
  'New York',
  'Moskau',
  'Peking',
  'Boston',
  'Köln',
  'St.Moritz',
  'Davos'
];

void main() {
  runApp(const MeineApp());
}

class MeineApp extends StatelessWidget {
  const MeineApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MeineHomePage(),
    );
  }
}

class MeineHomePage extends StatelessWidget {
  const MeineHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('List View Demo'),
      ),
      body: erzeugeListe4(),
    );
  }
}


Widget erzeugeListe4() {
  var liste = ListView.separated(
    itemCount: meineListe.length,
    separatorBuilder: (context,index){
      return Text('Ein Text als Separator');
    },
    itemBuilder: (context, index) {
      return Card(
        child: Padding(
          padding: const EdgeInsets.all(5.0),
          child: ListTile(
            title: const Text(
              'Stadt:',
              style: TextStyle(
                fontSize: 20.0,
              ),
            ),
            leading: const CircleAvatar(
              backgroundImage: AssetImage('lib/bilder/officeWorker.png'),
            ),
            trailing: Text(
              meineListe[index],
              style: const TextStyle(
                fontSize: 15.0,
              ),
            ),
          ),
        ),
      );
    },
  );
  return liste;
}

Der Code ist in dieser Form lauffähig, ich werde ihn aber nun ergänzen.

Floating Action Button


Dieser Button ist Teil der Scaffold(...) Struktur und dementsprechend muss ich ihn dort anlegen:


    return Scaffold(
      appBar: AppBar(
        title: const Text('List View Demo'),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: (){},
        child: Icon(Icons.add),

      ),
      body: erzeugeListe4(),
    );

Wie normale Buttons auch, verfügt er über einen onPressed(...) Parameter. Ihm muss ich eine anonyme Funktion übergeben, welche ausgeführt wird, wenn der Button benutzt wird. Im Code oben habe ich hier (...){...}. Der Code steht für eine leere Funktion und ist eigentlich nur ein Platzhalter. Genau so gut hätte ich NULL verwenden können. Der Code ist so lauffähig, aber es passiert natürlich nichts, wenn man den Button klickt.

Als child: übergebe ich oben ein Icon. Die einfachste Variante um einen Button zu erzeugen.

Jetzt ist es nicht ideal eine leere Funktion zu verwenden. Ich ergänze den Code um debugPrint(...). Diese Funktion schreibt einen Text in die Console. Zusätzlich verwende ich einen tooltip. Dieser wird angezeigt wenn der Button lange geklickt bleibt:


    return Scaffold(
      appBar: AppBar(
        title: const Text('List View Demo'),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: (){
            debugPrint('Button benutzt');
          },
        child: Icon(Icons.add),
        tooltip: 'Mein Button',

      ),
      body: erzeugeListe4(),
    );

Das sind letztendlich nicht viele Zeilen Code. Das Ergebnis:

avd vier

Wenn der Button nun benutzt wird, siehst Du das in der Console:

console eins

Natürlich hat der Floating Action Button noch wesentlich mehr Parameter, die Du verwenden kannst. Am besten schaust Du dir dieses Widget im Detail an. Zum Beispiel musst Du nicht unbedingt ein Icon als Button verwenden !

Snack Bar


Das zweite Topic dieses Artikels ist die Snack Bar. Als Code Basis kannst Du wieder den Code oben verwenden. Ob Du die Ergänzungen für den Floating Action Button verwendest oder nicht spielt dabei keine Rolle !

Als erstes definiere ich eine Funktion:

void zeigeSnackBar(){
  var snackBar = const SnackBar(
      content: Text('data')
  );
}

Diese weist der Variablen var ein SnackBar(...) Widget zu. Der einzige verwendete Parameter ist content:
Der Code oben ist aber noch nicht vollständig. Da die Funktion am Ende ein Widget in den Widget Baum einfügt, benötigt sie auch einen context dazu:


void zeigeSnackBar(BuildContext context){
  var snackBar = const SnackBar(
      content: Text('data')
  );
  ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

Dieser context wird in der ScaffoldMessenger.of(...) Funktion verwendet, welche wiederum mit showSnackBar(...) die Variable snackBar verarbeitet.

Im Hauptcode ganz oben, verwende ich das ListTile(...) Widget um die einzelnen Elemente der Liste zu erstellen. Dieses verfügt auch über eine onPressed: Möglichkeit:


child: ListTile(
            title: const Text(
              'Stadt:',
              style: TextStyle(
                fontSize: 20.0,
              ),
            ),
            leading: const CircleAvatar(
              backgroundImage: AssetImage('lib/bilder/officeWorker.png'),
            ),
            trailing: Text(
              meineListe[index],
              style: const TextStyle(
                fontSize: 15.0,
              ),
            ),
            onTap:() {
              zeigeSnackBar(context);
            }
          ),

Mit zeigeSnackBar(context) erhält nun jedes Listen Element eine Snack Bar, sollte das Element benutzt werden.

Nun ändere ich den Code so ab, das in der Snack Bar auch der Städtename angezeigt wird:

import 'package:flutter/material.dart';

List meineListe = [
  'Riad',
  'Zürich',
  'Hamburg',
  'London',
  'New York',
  'Moskau',
  'Peking',
  'Boston',
  'Köln',
  'St.Moritz',
  'Davos'
];

void main() {
  runApp(const MeineApp());
}

class MeineApp extends StatelessWidget {
  const MeineApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MeineHomePage(),
    );
  }
}

class MeineHomePage extends StatelessWidget {
  const MeineHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('List View Demo'),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: (){
            debugPrint('Button benutzt');
          },
        child: const Icon(Icons.add),
        tooltip: 'Mein Button',

      ),
      body: erzeugeListe4(),
    );
  }
}


Widget erzeugeListe4() {
  var liste = ListView.separated(
    itemCount: meineListe.length,
    separatorBuilder: (context,index){
      return const Text('Ein Text als Separator');
    },
    itemBuilder: (context, index) {
      return Card(
        child: Padding(
          padding: const EdgeInsets.all(5.0),
          child: ListTile(
            title: const Text(
              'Stadt:',
              style: TextStyle(
                fontSize: 20.0,
              ),
            ),
            leading: const CircleAvatar(
              backgroundImage: AssetImage('lib/bilder/officeWorker.png'),
            ),
            trailing: Text(
              meineListe[index],
              style: const TextStyle(
                fontSize: 15.0,
              ),
            ),
            onTap:() {
              zeigeSnackBar(context,meineListe[index]);
            }
          ),
        ),
      );
    },
  );
  return liste;
}
void zeigeSnackBar(BuildContext context,String stadt){
  var snackBar = SnackBar(
      content: Text(stadt)
  );
  ScaffoldMessenger.of(context).showSnackBar(snackBar);
}

Eigentlich ist es nur eine kleine Änderung: zeigeSnackBar(...) hat jetzt einen weiteren Parameter: String stadt. Beim Aufruf der Funktion übergebe ich dazu  meineListe[index], die auf die aktuelle Zeichenkette in der Städte Liste verweist. Im nächsten Artikel werde ich mir SnackBarAction(...) ansehen. Bis bald !😀

avd fünf


Kommentare

Beliebte Posts aus diesem Blog

Material Design in Flutter Teil 2

Listen in Dart (2021): Part 1 List.filled List.empty und List.add

Dart Basic: Listen Part 1