简体   繁体   中英

How to call setState alongside FutureBuilder in flutter without resetting the ExpansionTile?

Inside every ExpansionTile I've to call a FutureBuilder to get the dynamic data from server. The Future Builder Being Triggered only on Expanded so as to show the dynamic data as children of ExpansionTile .

 ListView(
    padding: EdgeInsets.all(16),
    children: widget.list.map((item) {
      return Card(
        elevation: 5,
        shape: RoundedRectangleBorder(
          side: BorderSide(color: Colors.white70, width: 1),
          borderRadius: BorderRadius.circular(10),
        ),
        child: ExpansionTile(
          leading: Icon(
            item["status"] != 3 ? Icons.warning : Icons.verified_user,
            color: item["status"] != 3 ? Colors.yellow[900] : Colors.green,
          ),
          title: Text(item["service_type"]),
          subtitle: Text(DateFormat('dd MMMM yyyy')
              .format(DateTime.parse(item["created_at"]))
              .toString()),
          onExpansionChanged: (value) {
            setState(() {
              timelineValue = value;
            });
          },
          children: <Widget>[
            timelineValue
                ? FutureBuilder(
                    future: getTimeline(timelineValue, item["id"]),
                    builder:
                        (BuildContext context, AsyncSnapshot snapshot) {
                      if (snapshot.hasData) {
                        // print(jsonDecode(snapshot.data.body).runtimeType);
                        Map map = jsonDecode(snapshot.data.body);
                        var currentstatus =
                            CurrentStatusModel.fromJson(map);
                        return Card(
                          shape: RoundedRectangleBorder(
                            side:
                                BorderSide(color: Colors.white70, width: 1),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          child: Container(
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(10),
                                color: secondaryColour),
                            height: 250,
                            padding:
                                EdgeInsets.only(top: 8, right: 8, left: 8),
                            child: SingleChildScrollView(
                              child: Column(
                                children: <Widget>[
                                  getTimelinetile(
                                      heading: "ഫോം ലഭിച്ചു.",
                                      subtitle:
                                          "സേവനത്തിനായുള്ള നിങ്ങളുടെ അപേക്ഷ ലഭിച്ചു.",
                                      isFirst: true,
                                      isLast: false,
                                      side: "left",
                                      isInactive: false),
                                  currentstatus.isProcessing == 1
                                      ? getTimelinetile(
                                          heading: "പ്രോസസ്സിംഗ് ആരംഭിച്ചു",
                                          subtitle: currentstatus
                                                      .isProcessingDesc !=
                                                  null
                                              ? currentstatus
                                                  .isProcessingDesc
                                              : "ഞങ്ങളുടെ സ്റ്റാഫുകൾ‌ ഇപ്പോൾ‌ നിങ്ങളുടെ അപ്ലിക്കേഷൻ‌ പരിശോധിക്കുന്നു.",
                                          isFirst: false,
                                          isLast: false,
                                          side: "right",
                                          isInactive: false)
                                      : Container(),
                                  currentstatus.documentsRequired == 1
                                      ? getTimelinetile(
                                          heading: "രേഖകൾ ആവശ്യമാണ്",
                                          subtitle: currentstatus
                                                      .documentsRequiredDesc !=
                                                  null
                                              ? currentstatus
                                                  .documentsRequiredDesc
                                              : "നിങ്ങളുടെ അപേക്ഷയുമായി മുന്നോട്ട് പോകാൻ രേഖകൾ ആവശ്യമാണ്.",
                                          isFirst: false,
                                          isLast: false,
                                          side: "left",
                                          isInactive: false)
                                      : Container(),
                                  currentstatus.documentsRequired == 1
                                      ? getTimelinetile(
                                          heading: currentstatus
                                                      .documentsReceived ==
                                                  1
                                              ? "രേഖകൾ ലഭിച്ചു"
                                              : "രേഖകൾ ഇതുവരെ ലഭ്യമായിട്ടില്ല.",
                                          subtitle: currentstatus
                                                      .documentsReceived ==
                                                  1
                                              ? (currentstatus
                                                          .documentsReceivedDesc !=
                                                      null
                                                  ? currentstatus
                                                      .documentsReceivedDesc
                                                  : "നിങ്ങൾ അയച്ച രേഖകൾ ഇപ്പോൾ ഞങ്ങളുടെ എക്സിക്യൂട്ടീവ് പരിശോധിച്ചുറപ്പിക്കുന്നു.")
                                              : "ഞങ്ങളുടെ സ്റ്റാഫുകൾ നിങ്ങളുടെ ഭാഗത്തു നിന്നുള്ള രേഖകൾക്കായി കാത്തിരിക്കുന്നു.",
                                          isFirst: false,
                                          isLast: false,
                                          side: "right",
                                          isInactive: currentstatus
                                                      .documentsReceived ==
                                                  1
                                              ? false
                                              : true)
                                      : Container(),
                                  currentstatus.paymentRequired == 1
                                      ? getTimelinetile(
                                          heading: "പേയ്‌മെന്റ് ആവശ്യമാണ്.",
                                          subtitle:
                                              "ഞങ്ങളുടെ സേവനവുമായി തുടരാൻ പേയ്‌മെന്റ് ആവശ്യമാണ്.",
                                          isLast: false,
                                          isFirst: false,
                                          side: "left",
                                          isInactive: false,
                                        )
                                      : Container(),
                                  currentstatus.paymentRequired == 1
                                      ? getTimelinetile(
                                          heading: currentstatus
                                                      .paymentReceived ==
                                                  1
                                              ? "പേയ്മെന്റ് ലഭിച്ചു"
                                              : "പേയ്‌മെന്റ് ഇതുവരെ ലഭിച്ചിട്ടില്ല.",
                                          subtitle: "test",
                                          isFirst: false,
                                          isLast: false,
                                          side: "right",
                                          isInactive: currentstatus
                                                      .paymentReceived ==
                                                  1
                                              ? false
                                              : true)
                                      : Container(),
                                  getTimelinetile(
                                      heading: currentstatus.formFinished ==
                                              1
                                          ? "സേവനം പൂർത്തിയായി"
                                          : "സേവനം പൂർത്തീകരിച്ചിട്ടില്ല",
                                      subtitle: currentstatus
                                                  .formFinished ==
                                              1
                                          ? "നിങ്ങളുടെ അപ്ലിക്കേഷൻ ഇതുവരെ പൂർത്തീകരിച്ചിട്ടില്ല."
                                          : "നിങ്ങളുടെ അപ്ലിക്കേഷൻ ഇതുവരെ പൂർത്തിയായിട്ടില്ല.",
                                      isLast: true,
                                      isFirst: false,
                                      side: "left",
                                      isInactive:
                                          currentstatus.formFinished == 1
                                              ? false
                                              : true),
                                  Card(
                                    color: Colors.grey[900],
                                    shape: RoundedRectangleBorder(
                                      side: BorderSide(
                                          color: Colors.white70, width: 1),
                                      borderRadius:
                                          BorderRadius.circular(10),
                                    ),
                                    margin: EdgeInsets.all(20.0),
                                    child: Container(
                                      child: Column(
                                        children: <Widget>[
                                          ListTile(
                                            title: Text(
                                              'example',
                                              style: TextStyle(
                                                  fontSize: 18,
                                                  color: Colors.white),
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        );
                      }
                      if (snapshot.hasError) {
                        return Container();
                      }
                      return Container(
                          height: 30.0,
                          child: LoadingIndicator(
                            indicatorType: Indicator.ballBeat,
                            color: primaryColour,
                          ));
                    })
                : Container()
          ],
        ),
      );
    }).toList(),
  ),

and the future function being -

Future getTimeline(value, id) async {
    if (timelineValue == true) {
      return await http.get(
          "http://" + restEndpoint + "/akshaya/public/api/get_timeline/$id");
    }
  }

The issue is for every onExpansionChange the setState is being called which rebuilds the widget tree and mess up the current state of the ExpansionTile . To be specific when collapsing one ExpansionTile , children of every other ExpansionTile collapses with the trailing botton pointing to Expanded mode.

Your problem seems to be, that you have a single variable timelineValue that you use for every expansion.

You need one variable per tile .

Add another boolean property to whatever class your widget.list holds and use the respective property of the current item instead of your single variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM