Return of the ListView (Flutter)

Return of the ListView
In meinem zweiten Post zu diesem Thema geht es um zwei Varianten von ListView. Im letzten Post haben wir gelernt, das ListView(...) in der Grundversion nur für eine kleine Anzahl an Einträgen empfohlen wird !

Die Entwickler begründen das damit, das Flutter bei dieser Variante jeden Listeneintrag erstellt. Egal ob er auf dem Bildschirm sichtbar ist oder nicht.

In realen Anwendungen kommt es aber oft vor, das man nicht genau weiss, wie viele Einträge eine Liste haben wird. Ein gutes Beispiel dafür ist eine Kontaktliste. Wahrscheinlich wird sie mit der Zeit grösser, kann aber auch wieder schrumpfen. 

Hier kommt ListView.builder(...) ins Spiel. Wie builder schon vermuten lässt, wird etwas aufgebaut.

ListView.builder

Als Basis für den Code nehme ich das Gerüst vom ersten Post zu diesem Thema:

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: erzeugeListe3() ,
    );
  }
}

Die Liste selbst werden wir in der Funktion erzeugeListe3(...) erstellen.

Widget erzeugeListe3(){
  var liste = ListView.builder(
    itemCount: meineListe.length ,
    itemBuilder:(context,index){
      return Card(
        child: Padding(padding: const EdgeInsets.all(10.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;
}

Im Code oben setzen wir nun ListView.builder(...) ein. Dabei ist meineListe, eine Liste von Zeichenketten.
itemCount: erwartet die Anzahl der Listeneinträge. Diese Zahl ermitteln wir mit meineListe.length.

itemBuilder

itemBuilder: erwartet als Parameter die Funktion, die die einzelnen Listeneinträge erstellt. Im Code oben verwende ich ein Card(...) Widget. Dieses hat als child: ein Padding(...) Widget.
Das ListTile(...) Widget fungiert als Kind von Padding und hat die bereits vom letzten Post zu diesem Thema bekannten Einträge.
Text(meineListe[index] generiert pro Listeneintrag den individuellen Text. Man ist aber ziemlich frei, wie man itemBuilder gestaltet. Wichtig ist nur das ein return Statement verwendet wird, welches den erstellten Listeneintrag retourniert.

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

Die Liste die ich für dieses Beispiel verwendet habe ist sehr einfach. Man könnte aber auch zum Beispiel eine Klasse erstellen mit diversen Parametern. Die dann erzeugten Klassenobjekte in einer Liste anordnen und diese Liste anschliessend mit itemBuilder erstellen.
avd eins

Die nächste Variante von ListView(...) die ich testen möchte ist

ListView.separated


Im Bild oben sieht man zwischen den einzelnen Listeneinträgen einen Abstand.  Solch einen Abstand kann man auf verschiedene Arten erzeugen. Im Beispiel oben ist er auf die default Einstellung von Card(...) für den margin: Parameter zurückzuführen. ListView bietet aber einen Konstruktor an, der sich speziell um dieses Thema kümmert, ListView.separated(...) .

Widget erzeugeListe4() {
  var liste = ListView.separated(
    itemCount: meineListe.length,
    separatorBuilder: (context,index){
      return Divider(
        color: Colors.black,
        thickness: 2.0,
        height: 4.0,
      );
    },
    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;
}

erzeugeListe4(...) hat einen großen Unterschied zu erzeugeListe3. ListView.separated verlangt von uns zwei builder Funktionen, itemBuilder und separatorBuilder.

Mit separatorBuilder: erstellen wir das Widget, das als Trennelement zwischen Listeneinträgen benutzt wird. Im Code oben verwende ich das Divider(...) Widget, welches nichts anderes macht als eine horizontale Linie zu ziehen.

avd zwei

Du könntest dem separatorBuilder: auch ein anderes Widget übergeben. Zum Beispiel Text:

avd drei


Das war es für diesen Post. Sollte es Fragen geben, schreibt mir in den Kommentaren. Bis bald 😀!

Kommentare

Beliebte Posts aus diesem Blog

Flutter und JSON

Flutter BloC Pattern 1

Dart Basic: Parameter in Funktionen