Juju
Juju

Reputation: 449

Flutter/Dart Build a different widget every x item with ListView.builder

I want to display a special widget with listView.builder every fourth item.

I got these two lists

List<Event> events = [];
List<SpecialEvent> specialEvent = [];

These lists get filled by two Streambuilder like so


StreamBuilder(
        stream: stream,
        builder: (BuildContext context,
            AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
          if (!snapshot.hasData) {
            //Spinner
          }
          events = snapshot.data.map((doc) => Event.fromDocument(doc)).toList();
          if (events.isEmpty) {
            //Code here
          }
          return StreamBuilder(
              stream: stream,
              builder: (BuildContext context,
                  AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
                if (!snapshot.hasData) {
                  //Spinner
                }
                specialEvents = snapshot.data
                    .map((doc) => specialEvents.fromDocument(doc))
                    .toList();

                eventCount = 0;
                specialEventCount = 0;

                return Flexible(
                  child: ListView.builder(
                    itemCount: events.length + specialEvents.length,
                    itemBuilder: (context, index) {

                      int newIndex = index + 1;
                      if (index != 0 &&
                              newIndex % 4 == 0 &&
                              specialEventCount.length > specialEventCount ||
                          specialEventCount.length > specialEventCount &&
                              events.length <= eventCount) {
                        specialEventCount += 1;
                        return buildSpecialEvent(specialEventCount - 1);
                      } else if (events.length > eventCount) {
                        eventCount += 1;
                        return buildEvent(eventCount - 1);
                      } else {
                        return Text("");
                      }
                    },
                  ),
                );
              });
        },
      );

This code works really well when it comes to the initial list view build. Every fourth item is a specialEvent.

The issue: The app user can tap on each of these events/specialEvents and gets navigated to a different screen. There the user can do some stuff and change data inside the database. This leads to a rebuild of the list view. Depending on the position inside of the list view the builder does not start to rebuild the widget with index 0. That in turn leads to a chaos with the evenCount and the specialEventcount and everything gets mixed up.

Does anybody know how to proper solve this issue? I guess there has to be a better solution to build a special widget every fourth item than mine.

Upvotes: 1

Views: 1797

Answers (1)

Mr Random
Mr Random

Reputation: 2218

Instead of ListView.builder, use ListView.separated,

hear is an example snippet

ListView.separated(
        itemCount: 40,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('$index'),
          );
        },
        separatorBuilder: (context, index) {
          return index == 0
              ? SizedBox.shrink()
              : index % 4 == 0
                  ? Container(
                      height: 20,
                      color: Colors.red,
                    )
                  : SizedBox.shrink();
        },
      ),

Upvotes: 1

Related Questions