如何在不重新设置ExpansionTile的情况下在Flutter中与FutureBuilder一起调用setState?

时间:2020-07-29 08:41:12

标签: flutter asynchronous dart flutter-layout

在每个ExpansionTile中,我必须调用一个FutureBuilder以从服务器获取动态数据。仅在展开时触发Future Builder,以便将动态数据显示为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(),
  ),

并且将来的功能是-

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

问题是每个onExpansionChange都被调用setState,这会重建小部件树并弄乱ExpansionTile的当前状态。具体来说,当一个ExpansionTile崩溃时,其他ExpansionTile的子项会崩溃,尾随的botton会指向扩展模式。

1 个答案:

答案 0 :(得分:0)

您的问题似乎是,您有一个变量- name: call an api vars: cust_id: "123" uri: url: "url" url_username: "username" url_password: "password" force_basic_auth: yes method: PUT headers: xyz: true body_format: json body: "{{ cust_id }}" 用于 每次扩展。

您需要每个图块一个变量

向您的timelineValue拥有的任何类添加另一个布尔属性,并使用当前项目的相应属性,而不是单个变量。