Flutter 颤振:当我抛出异常时,生成器在未来的生成器中调用两次
我试图在future builder上使用snackbar显示错误。因此,在initState方法上创建future方法实例后:Flutter 颤振:当我抛出异常时,生成器在未来的生成器中调用两次,flutter,flutter-layout,future,Flutter,Flutter Layout,Future,我试图在future builder上使用snackbar显示错误。因此,在initState方法上创建future方法实例后: Future<DetailModel> futureDetail; ... @override void initState() { futureDetail = DetailProvider().detailProvider(widget.id); super.initState(); } 在futur
Future<DetailModel> futureDetail;
...
@override
void initState() {
futureDetail =
DetailProvider().detailProvider(widget.id);
super.initState();
}
在futureBuilder中,我使用如下:
Center(
child: SingleChildScrollView(
child: FutureBuilder(
future: futureDetail,
builder:
(context, AsyncSnapshot<DetailProductModel> snapshot) {
if (!snapshot.hasError ||
snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
if (snapshot.hasData && snapshot.data.data != null) {
return Container();
}
if (snapshot.hasError &&
snapshot.error != null &&
snapshot.data == null) {
WidgetsBinding.instance.addPostFrameCallback((_) =>
showSnackbar(snapshot.error.toString(), context));
return Container();
} else {
return Center(
child: Text('failed to load'),
);
}
},
),
),
),
detailProvider方法调用http服务,在我的示例中,我抛出SocketException以获取生成器上的错误并显示snackbar
我知道future builder是用于显示每个状态的小部件,但我想
展示蛇吧
但是生成器被调用了两次,snackbar显示了两次错误?
我检查了这三个条件是否相同snapshot.hasError和snapshot.error!=两次生成中的null和snapshot.data==null。我怎样才能避免显示两次snakbar?更新:我共享的代码有问题。请看这个
首先,始终在FutureBuilder之外创建SnackBar,因为FutureBuilder经常被调用,因此它会导致无限循环。您可以做的是使用catchError。在使用我们已经声明的变量创建新的SnackBar之前,您仍然可以检查是否存在活动SnackBar
您将看到SnackBar只显示一次,即使在您运行下面的代码时我调用了三次
应用相同的方法更新您自己的代码:
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
bool snackBarActive = false;
Future<String> futureDetail;
@override
void initState() {
futureDetail = Future<String>.error('An error Occurred').catchError((errText) {
showSnackBar(errText);
showSnackBar(errText);
showSnackBar(errText);
});
super.initState();
}
void showSnackBar(String errText) {
if (!snackBarActive) {
setState(() {
snackBarActive = true;
});
WidgetsBinding.instance.addPostFrameCallback((_) => Scaffold.of(context)
.showSnackBar(SnackBar(
content: Text(errText),
))
.closed
.whenComplete(() {
setState(() {
snackBarActive = false;
});
}));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: FutureBuilder(
future: futureDetail,
builder: (context, AsyncSnapshot<String> snapshot) {
if (!snapshot.hasError &&
snapshot.hasData &&
snapshot.data != null) {
return Container();
} else {
return Center(
child: Text('failed to load'),
);
}
},
),
),
),
);
}
}
如果您只是打印快照,那么您在日志上看到了什么;作为构建器中的第一行@pskink和您的有状态小部件也构建了两次?这是全文@pskink