【发布时间】:2020-07-29 08:41:12
【问题描述】:
在每个ExpansionTile 内部,我必须调用FutureBuilder 从服务器获取动态数据。 Future Builder 仅在 Expanded 时触发,以便将动态数据显示为 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 的子代都会折叠,尾随按钮指向展开模式。
【问题讨论】:
-
请正确复制您的代码。有打开的标签和缺少的闭包,很难理解和帮助你。另外,您能否更明确地解释一下您的最后一段?由于
setStates和未来的构建器,您的小部件是否正在循环重建? -
不,它没有循环播放。 ExpansionTiles 的数量是动态的,并且在我使用
FutureBuilder的http get 方法之后再次接收到每个ExpansionTile 的扩展主体(子项)内的内容。但是,当展开多个ExpansionTiles,然后尝试关闭一个“ExpansionTile”时,每个其他ExpansionTile的展开主体都会关闭,而展开/折叠按钮仍指向展开方向。当我在onExpansionChanged回调中使用 setState 时,问题就发生了。 @JoãoSoares -
我只想在
ExpansionTile展开时触发 FutureBuilder。所以没有setState我无法触发FutureBuilder。请询问您是否需要更多详细信息,并对英语不好表示抱歉。 @JoãoSoares -
我想我现在明白了这个问题,而且我相信我以前见过它。我会尝试在本地复制它。
-
@JoãoSoares 感谢您的回访和您的时间。我希望你能解决它。
标签: flutter asynchronous dart flutter-layout