Home > Software engineering >  How to work with listviews correctly for displaying text
How to work with listviews correctly for displaying text

Time:07-17

I'm trying to display an message, but unfortunately I think I'll need to change my method.

So I've resumed some code

                      child: FutureBuilder<List<Product>>(
                          future: products,
                          builder: (context, snapshot) {
                            if (!snapshot.hasData) {
                              return const Center(
                                child: CircularProgressIndicator(),
                              );
                            }

                            final products = snapshot.data!;
                            return Padding(
                                padding: const EdgeInsets.all(10.0),
                                child: ListView.builder(
                                    itemCount: products.length, // currently has 400 items
                                    itemBuilder: (context, index) {
                                      if (difference == 0) {
                                        return cardUI(
                                ...
                                        );
                                      } else {
                                        return Text('Nothing to display!');
                                      }
                                    }));
                          })),

How can I manage to return the message only one time? Do I need to change all the code? Since it's displaying almost 250 times 'Nothing to display'

Thank you!

Edit: This is what I'm using to calculate the difference!

                                    DateTime productExpire = DateTime.parse(products[index].date);

                                     
                                      final productDate = productExpire;
                                      final today = DateTime.now();
                                      final difference = calcDays(
                                          today, productDate);

CodePudding user response:

You want to show a single error if the listview.builder does not have any data right? Hope I am not getting you wrong. If so you can use the ternary operator where you have mentioned the listview.builder to make it conditional.

or you can try to update the item count with condition.

itemcount: difference ==0? products.length : 1,

CodePudding user response:

After getting all products filter them and create another list of product that will satisfy difference==0.

 final products = snapshot.data!;
 
 List<Product> temp = [];
 // temp = products.where((p) => validation(p) == 0).toList();

 for(final p in products)
   {
     int difference = yourValidation(p);
     if(difference == 0) temp.add(p);
   }

   //...
   child: ListView.builder(
     itemCount: temp.length,

More about List

CodePudding user response:

The solution that comes to mind is to make products only equal to the products that have a difference of days from today of zero, so then based on products.length you can either return the Text() (if products.length == 0) or call the ListView.builder (if products.length > 0).

Basically:

Instead of this:

All products

products = [thisProdHasDifferenceOfZero, thisOneDoesnt, thisOneDoes, thisOneDoesnt, ...]

(products.length == 400 every time)

You can just have:

Only products that you want to work with

products = [thisProdHasDiffOfZero, thisOneToo, thisOneToo, ...]

(products.length <= 400)

In your code:

Instead of calculating the difference your way, use this:

This method calculates the difference between two dates, the one you're using may run into some bugs... check this answer for more information

    int daysBetween(DateTime from, DateTime to) {
        from = DateTime(from.year, from.month, from.day);
        to = DateTime(to.year, to.month, to.day);
        return (to.difference(from).inHours / 24).round();
    }

Then:

    child: FutureBuilder<List<Product>>(
        future: products,
        builder: (context, snapshot) {
            if (!snapshot.hasData) {
                return const Center(
                    child: CircularProgressIndicator(),
            );
        }
        final today = DateTime.now();
        final products = (snapshot.data! as List<Product>).where((product) => daysBetween(product.date, today) == 0).toList;
         // Now you know that every product inside 'products', if there's any, has a day difference of 0.
        return Padding(
        padding: const EdgeInsets.all(10.0),
        // 'products' can be empty since you may have 0 products that have the difference you are looking for.
        // In that case you return the text.
        child: (products.length == 0) ? 
            return Text('Nothing to display!');
            : return ListView.builder( // If products has one or more items...
                 itemCount: products.length,
                 itemBuilder: (context, index) {
                     return cardUI(
                         ...
                     );
                  }
              )
         ...
  • Related