Flutter:如何修复FutureBuilder中由setState引起的错误
Flutter:如何修复FutureBuilder中由setState引起的错误
我的目标是在点击ExpansionTile时加载一次Future并存储值,以便在Tile关闭然后重新打开时不再加载Future。
我的当前代码存在以下问题:
I/flutter (30528): 在构建期间调用了setState()或markNeedsBuild()。
I/flutter (30528): 无法标记此Dashboard小部件需要构建,因为框架已经在构建小部件的过程中。
I/flutter (30528): 只有在其祖先小部件当前正在构建时,小部件才能在构建阶段标记为需要构建。允许出现此异常的原因是框架
I/flutter (30528): 在构建子级之前构建父级小部件,这意味着脏子级将始终被构建。
I/flutter (30528): 否则,框架可能在此构建阶段不访问此小部件。
I/flutter (30528): 调用setState()或markNeedsBuild()的小部件是:
I/flutter (30528): Dashboard
I/flutter (30528): 在发生问题的调用时,正在构建的小部件是:
I/flutter (30528): FutureBuilder
我知道错误是什么意思,但我不知道如何修复它。这是我的当前代码:
class Dashboard extends StatefulWidget {
final ValueNotifier
final ValueNotifier
final int pageViewIndex;
Dashboard({this.pageViewScrollNotifier, this.pageViewIndexNotifier, this.pageViewIndex}) : super();
@override
_DashboardState createState() => _DashboardState();
}
class _DashboardState extends State
// 与"with AutomaticKeepAliveClientMixin"一起,这可以防止在切换选项卡时重建列表
// 这提高了性能并减少了数据库通信
@override
bool get wantKeepAlive => true;
Boat selectedBoat = Hive.box("selections").get("selectedBoat"); // 选定的船只
bool latestTrimExpanded = false;
// 最新的修剪,只加载一次
Trim latestTrim;
DateTime date;
DateFormat dateFormat = DateFormat("dd.MM.yyyy");
DateFormat timeFormat = DateFormat("HH:mm");
double satisfaction;
IconData icon;
Color color;
Map
@override
Widget build(BuildContext context) {
return Background(
pageViewScrollNotifier: widget.pageViewScrollNotifier,
pageViewIndexNotifier: widget.pageViewIndexNotifier,
pageViewIndex: widget.pageViewIndex,
child: ListView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: [
selectedBoat != null
? CustomCard(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Theme(
data: Theme.of(context).copyWith(dividerColor: Colors.transparent), // 使展开瓦片上下的分隔线透明
child: ExpansionTile(
leading: Icon(
FlutterIcons.settings_oct,
size: 30,
color: Color(Hive.box("configs").get("colors")["black"]),
),
title: Text(AppLocalizations.of(context).translate("trims.latestTrim"), style: Theme.of(context).textTheme.headline2),
maintainState: true,
onExpansionChanged: (value) {
setState(() {
latestTrimExpanded = value;
});
},
),
),
latestTrimExpanded && (latestTrim == null)
? FutureBuilder(
future: DatabaseInstance.trim.getLatestTimeOfBoat(selectedBoat.documentid),
builder: (context, futureSnapshot) {
if (futureSnapshot.connectionState != ConnectionState.done) {
return StandardLoading();
} else {
setState(() {
latestTrim = futureSnapshot.data;
date = latestTrim.time["ts"].first;
satisfaction = latestTrim.evaluation["satisfaction"].first;
icon = satisfactionIcon(satisfaction);
color = satisfactionColor(satisfaction);
Hive.box("configs").get("boatClasses")[Hive.box("selections").get("selectedBoat").boatClass]["trimTemplate"].forEach(
(key, value) {
if (!trimOptions.containsKey(key)) {
trimOptions[key] = value;
}
},
);
});
return Container();
}
},
)
: Container(),
latestTrimExpanded && (latestTrim != null)
? Container() // 占位符,将在FutureBuilder中加载的数据显示和访问在这里
: Container(),
],
),
)
: Container(),
],
),
);
}
}