Flutter ListView und Scrollen

ListView ist das am häufigsten verwendete scrollbare Listen-Widget in Flutter und wird verwendet, um scrollbare Inhaltslisten anzuzeigen.


ListView Grundlegende Verwendung

Beispiel: ListView Grundlegende Verwendung

// Methode 1: children-Parameter (geeignet für eine kleine Anzahl von Elementen)
ListView(
  children: [
    ListTile(title: Text('First item')),
    ListTile(title: Text('Second item')),
    ListTile(title: Text('Third item')),
  ],
)

// Methode 2: ListView.builder (geeignet für große oder unendliche Listen)
ListView.builder(
  itemCount: 100,
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item ${index + 1}'));
  },
)

// Methode 3: ListView.separated (mit Trennern)
ListView.separated(
  itemCount: 10,
  separatorBuilder: (context, index) => const Divider(),  // Divider
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item ${index + 1}'));
  },
)

Allgemeine Eigenschaften von ListView

EigenschaftBeschreibung
scrollDirectionScrollrichtung, standardmäßig Axis.vertical (vertikal).
reverseOb umgekehrt gescrollt werden soll
paddingListen-Padding
itemExtentFeste Elementhöhe für bessere Performance
prototypeItemPrototyp-Element zur Berechnung der Höhe

Beispiel: Horizontale ListView

// Liste mit horizontalem Scrollen
SizedBox(
  height: 120,  // Höhe muss gesetzt werden
  child: ListView.builder(
    scrollDirection: Axis.horizontal,  // Horizontales Scrollen
    itemCount: 20,
    itemBuilder: (context, index) {
      return Container(
        width: 100,
        margin: const EdgeInsets.symmetric(horizontal: 8),
        color: Colors.blue[100],
        child: Center(
          child: Text('Item $index'),
        ),
      );
    },
  ),
)

GridView - Raster-Layout

GridView wird zum Erstellen zweidimensionaler Rasterlisten verwendet.

Beispiel: GridView-Verwendung

// GridView.count - feste Anzahl von Spalten
GridView.count(
  crossAxisCount: 3,  // 3 Spalten
  children: List.generate(20, (index) {
    return Container(
      margin: const EdgeInsets.all(4),
      color: Colors.blue[100],
      child: Center(child: Text('${index + 1}')),
    );
  }),
)

// GridView.builder - dynamischer Aufbau
GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 4,  // 4 Spalten
    mainAxisSpacing: 8,  // Vertikaler Abstand
    crossAxisSpacing: 8,  // Horizontaler Abstand
    childAspectRatio: 1,  // Seitenverhältnis
  ),
  itemCount: 50,
  itemBuilder: (context, index) {
    return Container(
      color: Colors.green[100],
      child: Center(child: Text('${index + 1}')),
    );
  },
)

// GridView.extent - adaptive Spaltenanzahl
GridView.extent(
  maxCrossAxisExtent: 150,  // Maximale Spaltenbreite
  children: List.generate(20, (index) {
    return Container(
      margin: const EdgeInsets.all(4),
      color: Colors.orange[100],
      child: Center(child: Text('${index + 1}')),
    );
  }),
)

Scroll-Steuerung

Mit ScrollController können Sie die Scroll-Position steuern.

Beispiel: Scroll-Steuerung

class ScrollExample extends StatefulWidget {
  const ScrollExample({super.key});

  @override
  State<ScrollExample> createState() => _ScrollExampleState();
}

class _ScrollExampleState extends State<ScrollExample> {
  // Scroll-Controller erstellen
  late ScrollController _controller;

  @override
  void initState() {
    super.initState();
    _controller = ScrollController();
    // Auf Scroll-Ereignisse hören
    _controller.addListener(() {
      print('Scroll-Position: ${_controller.offset});
    });
  }

  @override
  void dispose() {
    // Controller freigeben
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // Schaltfläche zum Scrollen nach oben
        ElevatedButton(
          onPressed: () {
            // Nach oben scrollen
            _controller.animateTo(
              0,
              duration: const Duration(milliseconds: 500),
              curve: Curves.easeInOut,
            );
          },
          child: const Text('Nach oben scrollen'),
        ),
        // Liste
        Expanded(
          child: ListView.builder(
            controller: _controller,  // Controller binden
            itemCount: 100,
            itemBuilder: (context, index) {
              return ListTile(title: Text('Item ${index + 1}'));
            },
          ),
        ),
      ],
    );
  }
}

Slivers: Fortgeschrittenes Scrollen

CustomScrollView in Kombination mit Slivers kann komplexere Scrolleffekte erzielen.

Beispiel: Kollabierender Slivers-Effekt

// Scroll-Ansicht mit einklappbarer App-Leiste
CustomScrollView(
  slivers: [
    // App-Leiste einklappen
    SliverAppBar(
      expandedHeight: 200,  // Ausgeklappte Höhe
      pinned: true,  // Oben fixiert
      flexibleSpace: FlexibleSpaceBar(
        title: const Text('Einklappbarer Titel'),
        background: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.blue, Colors.purple],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
          ),
        ),
      ),
    ),
    // Listeninhalt
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('Element ${index + 1}')),
        childCount: 30,
      ),
    ),
  ],
)

// Raster-Sliver
CustomScrollView(
  slivers: [
    const SliverAppBar(
      title: Text('Bildraster'),
      pinned: true,
    ),
    SliverGrid(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      delegate: SliverChildBuilderDelegate(
        (context, index) => Card(
          child: Image.network('https://picsum.photos/200?$index'),
        ),
        childCount: 20,
      ),
    ),
  ],
)

Slivers bieten einen effizienten Weg, eine große Anzahl scrollender Elemente zu handhaben; sie rendern nur Elemente im sichtbaren Bereich und bieten dadurch eine gute Leistung.

Weitere Erweiterungen