[英]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.在每个ExpansionTile
中,我都必须调用FutureBuilder
来从服务器获取动态数据。 The Future Builder Being Triggered only on Expanded so as to show the dynamic data as children of ExpansionTile
. 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(),
),
and the future function being -和未来的 function 是 -
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
.问题是对于每个onExpansionChange
正在调用的setState
,它会重建小部件树并弄乱ExpansionTile
的当前 state 。 To be specific when collapsing one ExpansionTile
, children of every other ExpansionTile
collapses with the trailing botton pointing to Expanded mode.具体来说,当折叠一个ExpansionTile
时,每个其他ExpansionTile
的子代都会折叠,尾随 botton 指向 Expanded 模式。
Your problem seems to be, that you have a single variable timelineValue
that you use for every expansion.您的问题似乎是,您有一个用于每次扩展的变量timelineValue
。
You need one variable per tile .每个 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.将另一个 boolean 属性添加到您的widget.list
包含的任何 class 中,并使用当前项目的相应属性而不是您的单个变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.