Flutter : call getData function only when I click on expansion tile

Issue

I have a complex UI , am displaying a listViewbuilder composed of many expansion tiles.
At first , I retrieve the list of data show it , then I call on another function to which I give the id of my object to display details when I click on the expansion tile . The only problem here , is that the code complexity is too high , say we have 20 items in the list every time I call the function that returns the details of my item using futurebuilder or provider it will call the function 20 times even though I didn’t click on the expansion tile to view the details. I want to be able to call my future function only when I click on the expansion tile.
this is my view :
enter image description here

and this is my code using provider and future builder


child: FutureBuilder(
                      future: futureQrqc,
                      builder: (BuildContext context,
                          AsyncSnapshot<QrqcDetails?> snapshot) {
                        if (snapshot.hasData) {
                          String? backgroundImage;

                          String? _setImage() {
                            String _mTitle = "${snapshot.data!.type}";

                            if(_mTitle == "Delivery") {
                              backgroundImage = "assets/icons/delivery.png";
                            } else if(_mTitle == "Security") {
                              backgroundImage = "assets/icons/security.png";
                            }
                            else if(_mTitle == "Quality") {
                              backgroundImage = "assets/icons/quality.png";
                            }
                            else if(_mTitle == "Cost") {
                              backgroundImage = "assets/icons/Cost.png";
                            }
                            else if(_mTitle == "People") {
                              backgroundImage = "assets/icons/people.png";
                            }
                            print("_mTitle: $_mTitle");
                            print("_mTitle: $backgroundImage");
                            return backgroundImage; // here it returns your _backgroundImage value

                          }

                          return Column(
                            children: [
                              ConditionalBuilder(
                                condition: myQrqcListViewModel
                                    .articlesList[index].status ==
                                    'INIT',
                                builder: (context) => Container(
// ignore: prefer_const_constructors
                                  decoration: const BoxDecoration(
                                    borderRadius: BorderRadius.all(
                                        Radius.circular(20)),
                                  ),
                                  foregroundDecoration:
                                  const RotatedCornerDecoration(
                                    color: Colors.orange,
                                    geometry: BadgeGeometry(
                                        width: 40,
                                        height: 40,
                                        cornerRadius: 16),
                                    textSpan: TextSpan(
                                      text: 'INIT',
                                      style: TextStyle(
                                        fontSize: 10,
                                        letterSpacing: 1,
                                        fontWeight: FontWeight.bold,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ),
                                  child: ExpansionTile(
                                    title: Text(
                                      myQrqcListViewModel
                                          .articlesList[index].id
                                          .toString(),
                                      style: const TextStyle(
                                          fontSize: 18,
                                          fontWeight: FontWeight.bold,
                                          color: Colors.black),
                                    ),
                                    leading:  QrqcCardLeaing(
                                      imgPath: _setImage(),
                                    ),
                                    subtitle: Text(myQrqcListViewModel
                                        .articlesList[index].title),
                                    trailing: QrqcCardtrailing(percent:   myQrqcListViewModel
                                        .articlesList[index]
                                        .progress
                                        .toString(),text:   myQrqcListViewModel
                                        .articlesList[index]
                                        .progress
                                        .toString(),),
                                    children: [
                                      QrqcDetailsCardFirstRow(product: snapshot.data?.product?? "No product" ,role: myQrqcListViewModel
                                          .articlesList[index].role, ),
                                      const SizedBox(height: 10),
                                      Row(
                                        children: [
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/location.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data!.perimeter,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                          const SizedBox(width: 50),
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/calendar.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(

                                              child: Text(
                                                convertDateTimeDisplay(snapshot.data!.creation_date),

                                                style: TextStyle(fontSize: 10),
                                              )),
                                        ],
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  ),
                                ),
                                fallback: null,
                              ),
                              ConditionalBuilder(
                                condition: myQrqcListViewModel
                                    .articlesList[index].status ==
                                    'SUBMITTED',
                                builder: (context) => Container(
// ignore: prefer_const_constructors
                                  decoration: const BoxDecoration(
                                    borderRadius: BorderRadius.all(
                                        Radius.circular(20)),
                                  ),
                                  foregroundDecoration:
                                  const RotatedCornerDecoration(
                                    color: Colors.blueAccent,
                                    geometry: BadgeGeometry(
                                        width: 40,
                                        height: 40,
                                        cornerRadius: 16),
                                    textSpan: TextSpan(
                                      text: 'SUB',
                                      style: TextStyle(
                                        fontSize: 10,
                                        letterSpacing: 1,
                                        fontWeight: FontWeight.bold,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ),
                                  child: ExpansionTile(
                                    leading:  QrqcCardLeaing(
                                      imgPath: _setImage(),
                                    ),
                                    title: Text(
                                      myQrqcListViewModel
                                          .articlesList[index].id
                                          .toString(),
                                      style: const TextStyle(
                                          fontSize: 18,
                                          fontWeight: FontWeight.bold,
                                          color: Colors.black),
                                    ),
                                    subtitle: Text(myQrqcListViewModel
                                        .articlesList[index].title),
                                    trailing: Column(
                                      children: [
                                        Expanded(
                                            child: CircularPercentIndicator(
                                              radius: 20.0,
                                              lineWidth: 2.0,
                                              percent: double.parse(
                                                  myQrqcListViewModel
                                                      .articlesList[index]
                                                      .progress
                                                      .toString()) /
                                                  100,
                                              center: Text(
                                                myQrqcListViewModel
                                                    .articlesList[index]
                                                    .progress
                                                    .toString(),
                                                style: const TextStyle(
                                                    fontSize: 10),
                                              ),
                                              progressColor: kPrimaryColor,
                                            )),
                                      ],
                                    ),
                                    children: [
                                      Row(
                                        children: [
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/user.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                myQrqcListViewModel
                                                    .articlesList[index].role,
                                                style: const TextStyle(
                                                    fontSize: 10),
                                              )),
                                          const SizedBox(width: 50),
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/product.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data?.product?? "No product"  ,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                        ],
                                      ),
                                      const SizedBox(height: 10),
                                      Row(
                                        children: [
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/location.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data!.perimeter,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                          const SizedBox(width: 50),
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/calendar.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data!.creation_date,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                        ],
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  ),
                                ),
                                fallback: null,
                              ),
                              ConditionalBuilder(
                                condition: myQrqcListViewModel
                                    .articlesList[index].status ==
                                    'VALIDATED',
                                builder: (context) => Container(
// ignore: prefer_const_constructors
                                  decoration: const BoxDecoration(
                                    borderRadius: BorderRadius.all(
                                        Radius.circular(20)),
                                  ),
                                  foregroundDecoration:
                                  const RotatedCornerDecoration(
                                    color: Colors.green,
                                    geometry: BadgeGeometry(
                                        width: 40,
                                        height: 40,
                                        cornerRadius: 16),
                                    textSpan: TextSpan(
                                      text: 'VALID',
                                      style: TextStyle(
                                        fontSize: 10,
                                        letterSpacing: 1,
                                        fontWeight: FontWeight.bold,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ),
                                  child: ExpansionTile(
                                    leading:  QrqcCardLeaing(
                                      imgPath: _setImage(),
                                    ),
                                    title: Text(
                                      myQrqcListViewModel
                                          .articlesList[index].id
                                          .toString(),
                                      style: const TextStyle(
                                          fontSize: 18,
                                          fontWeight: FontWeight.bold,
                                          color: Colors.black),
                                    ),
                                    subtitle: Text(myQrqcListViewModel
                                        .articlesList[index].title),
                                    trailing: Column(
                                      children: [
                                        Expanded(
                                            child: CircularPercentIndicator(
                                              radius: 20.0,
                                              lineWidth: 2.0,
                                              percent: double.parse(
                                                  myQrqcListViewModel
                                                      .articlesList[index]
                                                      .progress
                                                      .toString()) /
                                                  100,
                                              center: Text(
                                                myQrqcListViewModel
                                                    .articlesList[index]
                                                    .progress
                                                    .toString(),
                                                style: const TextStyle(
                                                    fontSize: 10),
                                              ),
                                              progressColor: kPrimaryColor,
                                            )),
                                      ],
                                    ),
                                    children: [
                                      Row(
                                        children: [
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/user.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                myQrqcListViewModel
                                                    .articlesList[index].role,
                                                style: const TextStyle(
                                                    fontSize: 10),
                                              )),
                                          const SizedBox(width: 50),
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/product.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data?.product?? "No product"  ,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                        ],
                                      ),
                                      const SizedBox(height: 10),
                                      Row(
                                        children: [
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/location.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data!.perimeter,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                          const SizedBox(width: 50),
                                          Expanded(
                                            child: Image.asset(
                                              "assets/icons/calendar.png",
                                              width: 20,
                                              height: 20,
                                            ),
                                          ),
                                          Expanded(
                                              child: Text(
                                                snapshot.data!.creation_date,
                                                style: TextStyle(fontSize: 10),
                                              )),
                                        ],
                                      ),
                                      const SizedBox(height: 10),
                                    ],
                                  ),
                                ),
                                fallback: null,
                              ),
                              
                          );
                        } else if (snapshot.hasError) {
                          return NoDataUI();
                        }
                        print(snapshot.error.toString());
                        return const Center(
                            child: CircularProgressIndicator());
                      })


If anyone can help please don’t hesitate , this is an important issue to optimise my code before launching my app for users on stores . Thank you so much and happy coding 🙂

Solution

You can wrap your ExpansionTile with GestureDetector or InkWell and call the function in onTap method.

Answered By – Abhishek Doshi

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *