2

I am having a list presented by a ListView.builder and I use a Function to check if an object in the list is being searched, but I want to present a screen when no object was found. So the user knows that nothing was found but I am strugelling with it, the code looks something like that:

Container OnlyShow = Container(
    child: ListView.builder(
      itemCount: myList.length,
      itemBuilder: (context, index) {
        if (searchfunction(myList[index]) == true) {
          return myListObject(myList[index]);
        } else {
          return Container(height: 0, width: 0,);
        }
      },
    ),
  );

The search function itself is not the problem I only want to know how I could find out if the ListView.builder only returns empty containers, because that would mean that no objects equal the search and therefore nothing was found.

I have tried something like that:

Container OnlyShow = Container(
    child: ListView.builder(
      itemCount: myList.length,
      itemBuilder: (context, index) {
        if (searchfunction(myList[index]) == true) {
          if (howManyObjectsAreFalse > 0) {
            howManyObjectsAreFalse--;
            dismissNoResultsFoundScreen();
          }
          return myListObject(myList[index]);
        } else {
          if (howManyObjectsAreFalse < myList.length) {
            howManyObjectsAreFalse++;
          }
          if (howManyObjectsAreFalse == myList.length) {
            showNoResultsFoundScreen();
          }
          return Container(height: 0, width: 0,);
        }
      },
    ),
  );
  
  int howManyObjectsAreFalse = 0;

It should work like this when an empty Container is returned the count is incremented and when a Result is returned the count is decreased, So when the count hits the length of the list the NoResultScreen is being presented.

It does work but with some weird exceptions, sometimes the count seems to fluctuate between to values, even if the ListView.builder only returns empty Containers.

Note: The List is not empty I just return an empty container for every object in the list that is not equal to the search value. So I don't decrease the list or something

I hope someone can help me with a better way to achieve this.

11
  • the list is not empty Commented Jan 19, 2021 at 7:24
  • No nothing is found: when only empty containers are returned, myList remains the same, I dont't change myList i only look if searchfunction(myList) == true and if i return myList[index] and if not i return an empty Container Commented Jan 19, 2021 at 7:30
  • 1
    child: myList.where(searchfunction).isEmpty ? Text('nothing was found') : ListView.builder(...) Commented Jan 19, 2021 at 7:31
  • but honestly returning such Container(height: 0, width: 0,); is wrong: you should remove non existing data, and not showing empty widgets Commented Jan 19, 2021 at 7:42
  • 1
    btw cannot you use a tmp array like: final tempArray = myList.where(searchfunction).toList(); ? and use it: tempArray.isEmpty? Text('nothing found') : ListView.builder(itemCount: tempArray.length, ... Commented Jan 19, 2021 at 7:59

4 Answers 4

3

The answer that @pskink gave did the trick:

child: myList.where(searchfunction).isEmpty ? Text('nothing was found') : ListView.builder(...)
Sign up to request clarification or add additional context in comments.

1 Comment

btw if you really want to go that way and use "invisible" containers then you could use faster (and using less memory) method: child: myList.any(searchfunction) ? ListView.builder(...) : Text('nothing was found')
2

I don't sure this is what you want

int howManyObjectsAreFalse = myList.length;
Container OnlyShow = Container(
    child: ListView.builder(
      itemCount: myList.length,
      itemBuilder: (context, index) {
        if (searchfunction(myList[index]) == true) {
            howManyObjectsAreFalse--;
          if (howManyObjectsAreFalse < myList.length) {
            dismissNoResultsFoundScreen();
          }
          return myListObject(myList[index]);
        } else {
          if (howManyObjectsAreFalse == myList.length) {
            showNoResultsFoundScreen();
          }
          return Container(height: 0, width: 0,);
        }
      },
    ),
  );

Comments

1

ListView.builder is a lazy list builder, so it will only build children which are currently rendered on the screen. u could do smth like this though.

  int searchResultsCnt = 0;
  final shownList = myList.map<Widget>((e) {
    if (searchFunction(e)) {
      searchResultsCnt++;
      return myListObject(e);
    }
    return Container(height: 0, width: 0);
  }).toList<Widget>();
  
  if (searchResultsCnt == 0)
    showNoResultsFoundScreen();
  else
    dismissNoResultsFoundScreen();
  
  return ListView.builder(
    itemCount: shownList.length,
    itemBuilder: (context, index) => shownList[index],
  );

Comments

1

ListView.builder Example when itemCount has no data to show text in body,

if (customerRegList.length != 0) {
      return ListView.builder(
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          itemCount: customerRegList == null ? 0 : customerRegList.length,
          itemBuilder: (BuildContext context, int index) {
            return Card(
child:Text('Hello World'),
 );
          });
    } else {
      return Center(
        child: Padding(
          padding: const EdgeInsets.only(top: 80.0),
          child: Text(
            'No Data Available!!',
            style: TextStyle(color: Colors.red, fontSize: 20.0, fontWeight: FontWeight.bold),
          ),
        ),
      );
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.