Flutter:仅当我单击扩展图块时才调用 getData 函数
我有一个复杂的 UI,正在显示一个由许多扩展图块组成的 listViewbuilder。 首先,我检索数据列表并显示它,然后调用另一个函数,向该函数提供对象的 id,以便在单击扩展图块时显示详细信息。这里唯一的问题是代码复杂性太高,假设每次我使用 futurebuilder 或提供者调用返回我的项目详细信息的函数时,列表中有 20 个项目,即使我没有调用该函数,它也会调用该函数 20 次请勿单击扩展图块来查看详细信息。我希望仅在单击扩展图块时才能调用未来的函数。 这是我的观点: 在此处输入图像描述
,这是我使用提供程序和未来构建器的代码
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());
})
如果有人可以提供帮助,请不要不要犹豫,这是在商店中为用户启动我的应用程序之前优化我的代码的一个重要问题。非常感谢您,编码愉快:)
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 :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
GestureDetector
或InkWell
包装ExpansionTile
并在onTap
方法中调用该函数。You can wrap your
ExpansionTile
withGestureDetector
orInkWell
and call the function inonTap
method.