I am trying to place an advertisement after every 3rd index. I got the required output but my problem in my case is i have a two type of List,

  1. List One has 50 datas in it.
  2. List two has only 5 datas.

When i tried with the below code.

ListView.separated(
                physics: NeverScrollableScrollPhysics(),
                padding: EdgeInsets.all(15),
                shrinkWrap: true,
                itemCount: articles.length,
                separatorBuilder: (context, index) => SizedBox(
                  height: 15,
                ),
                itemBuilder: (BuildContext context, int index) {
                  final Article article = articles[index];
                  final Sponsor sponsor = sponsors[index];
                  if(index %3 == 0 && index != 0) return SponsorCard(sponsor: sponsor, scaffoldKey: widget.scaffoldKey);
                  return Card4(article: article, heroTag: 'recent${article.id}', scaffoldKey: widget.scaffoldKey);
widget.scaffoldKey);
                },
              ),

i am getting range error since sponsor list reached its last position. error

The following RangeError was thrown building:
RangeError (index): Invalid value: Not in inclusive range 0..4: 49

What i need is that i need to make the sponsor list as loop so that if the List reached its last position it has to move again to the first position.

Can someone please help me on this.


Solution 1: vnaren001

You can create a new combined list as, and make sure both Article & Sponsor class should be child class of ListItem. OR you need to wrap Article & Sponsor classes under ListItem Wrapper class

List items = []

Now use the items with ListView :

ListView.separated(
            physics: NeverScrollableScrollPhysics(),
            padding: EdgeInsets.all(15),
            shrinkWrap: true,
            itemCount: items.length,
            separatorBuilder: (context, index) => SizedBox(
              height: 15,
            ),
            itemBuilder: (BuildContext context, int index) {
              if (item[index] is Articles){
                return SponsorCard(..);
              }else{
                  return Card4(...);
              }
            },
          );

Added Example on Request comment:

    class _ListItem {
      final bool isArticleType;
      final dynamic value;
      _ListItem(this.isArticleType, this.value);
    }

class Article {}

class Sponsor {}

List<_ListItem> createList(List<Article> articles, List<Sponsor> sponsors) {
  List<_ListItem> items = [];
  items.addAll(articles.map((e) => _ListItem(true, e)).toList());
  var index = 0;
  var sIndex = 0;
  for (var i = 0; i < articles.length && sIndex < sponsors.length; i++) {
    if (i != 0 && i % 3 == 0) {
      items.insert(index, _ListItem(false, sponsors[sIndex]));
      sIndex++;
      index++;
    }
    index++;
  }

  return items;
}


Solution 2: Elam

Thanks for your response guys.

I could achieve by the below code.

itemBuilder: (BuildContext context, int index) {
                  actualIndex = actualIndex +1;
                  if(sponsorIndex+1 >= sponsors.length){
                    sponsorIndex = -1;
                  }
                  if(index == 0 ){
                    articleIndex = -1;
                  }
                  if ((actualIndex-tempIndex) % 3 == 0 && actualIndex != 0 && (actualIndex-prevIndex) >=3 ) {
                    tempIndex = tempIndex +1;
                    prevIndex = actualIndex;
                    sponsorIndex = sponsorIndex + 1;
                    final Sponsor sponsor = sponsors[sponsorIndex];
                    return SponsorCard(sponsor: sponsor, scaffoldKey: widget.scaffoldKey);
                  }
                  articleIndex = articleIndex + 1;
                  final Article article = articles[articleIndex];
                  return Card4(article: article, heroTag: 'recent${article.id}', scaffoldKey: widget.scaffoldKey);
                },