How to manually assign the first element of a Listview.builder in Flutter?

Viewed 5244

I have a Flutter application, which displays events (stored in Cloud Firestore), on cards in a Listview.builder. I have a specific event, football. It has it's own, special cards. There can be multiple regular events in the list, but only one football event. I'd like to display this football event on the top of the list, as the first card. How can I achieve this?

My code so far:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fociapp/model/events.dart';
import 'package:fociapp/ui/event_card.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: Firestore.instance.collection("events").snapshots(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          return snapshot.hasData
              ? Container(
                  color: Colors.grey[850],
                  child: ListView.builder(
                    itemCount: snapshot.data.documents.length,
                    itemBuilder: (BuildContext context, int index) {
                      DocumentSnapshot events = snapshot.data.documents[index];
                      Event event = Event(
                          events["eventName"],
                          events["startTime"],
                          events["coverImageUrl"],
                          events["location"],
                          events["description"]);

                      return EventCard(event);
                    },
                  ),
                )
              : Center(
                  child: CircularProgressIndicator(),
                );
        });
  }
}

Event is a model class for the data coming from Firestore, EventCard is the widget, which displays the data in a card.
3 Answers

Just increase the ItemCount by one. And in your ItemBuilder if index is 0 return the Football-Card and if not return your normal cards (index - 1).

Like so:

ListView.builder(
    itemCount: snapshot.data.documents.length + 1,
    itemBuilder: (BuildContext context, int index) {
       if(index == 0) {
          // return Football-Card
       } else {
           DocumentSnapshot events = snapshot.data.documents[index - 1];
           Event event = Event(
               events["eventName"],
               events["startTime"],
               events["coverImageUrl"],
               events["location"],
               events["description"]);

            return EventCard(event);
        }
     },
),

In your ListView.builder, you can tell it to display something else based on its index. We can use an if statement to achieve this. Your index will always start at 0 and will increment every after widget built. You can check if the index is 0 and display your football event when the index is 0.

ListView.builder(
                    itemCount: snapshot.data.documents.length,
                    itemBuilder: (BuildContext context, int index) {
                      if(index==0){
                      DocumentSnapshot events = snapshot.data.documents[index];
                      Event event = Event(
                          events["eventName"],
                          events["startTime"],
                          events["coverImageUrl"],
                          events["location"],
                          events["description"]);

                      return EventCard(event);
                      }
                      else{
                      //return your other things
                      }
                    },
                  ),
                )

You can only manipulate the data to meet the requirements, not the ListView.Like this:

class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return StreamBuilder(
            stream: Firestore.instance.collection("events").snapshots(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              return snapshot.hasData
                  ? Container(
                color: Colors.grey[850],
                child: createListView(snapshot.data.documents),
              )
                  : Center(
                child: CircularProgressIndicator(),
              );
            });
      }
    
      Widget createListView(List<DocumentSnapshot> documentList){
        // find football and move it to the start position.
        DocumentSnapshot football = documentList.indexWhere((element) => element.eventName == 'football');
        documentList.remove(football);
        documentList.insert(0, football);
    
        return ListView.builder(
          itemCount: documentList.length,
          itemBuilder: (BuildContext context, int index) {
            DocumentSnapshot events = snapshot.data.documents[index];
            Event event = Event(
                events["eventName"],
                events["startTime"],
                events["coverImageUrl"],
                events["location"],
                events["description"]);
    
            return EventCard(event);
          },
        );
      }
    }
Related