本文介绍了当我尝试在构建器中显示SnackBar时出现错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
这是我的main.dart
:
class MyApp extends StatelessWidget {
var login = new Login("xxxxxxx", "xxxxxxxxx");
final scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder(
future: login.main(),
builder: (context, snapshot) {
if (snapshot.hasData) {
_showSnackBar(snapshot.data);
return new Container();
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
),
),
),
);
}
_showSnackBar(var text) {
scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(text)));
}
}
我想在FutureBuilder中显示一个SnackBar,但是当我运行时,发生了一些错误:
I'd like to show a SnackBar in FutureBuilder, but when I run, something wrong occurs:
I/flutter ( 8918): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════
I/flutter ( 8918): The following assertion was thrown building
FutureBuilder<dynamic>(dirty, state:
I/flutter ( 8918): _FutureBuilderState<dynamic>#9d4af):
I/flutter ( 8918): setState() or markNeedsBuild() called during build.
I/flutter ( 8918): This Scaffold widget cannot be marked as needing to
build because the framework is already in the
I/flutter ( 8918): process of building widgets. A widget can be marked
as needing to be built during the build phase
I/flutter ( 8918): only if one of its ancestors is currently building.
This exception is allowed because the framework
I/flutter ( 8918): builds parent widgets before children, which means
a dirty descendant will always be built.
I/flutter ( 8918): Otherwise, the framework might not visit this
widget during this build phase.
I/flutter ( 8918): The widget on which setState() or markNeedsBuild()
was called was:
I/flutter ( 8918): Scaffold-[LabeledGlobalKey<ScaffoldState>#e4a3f]
(state: ScaffoldState#cf908(tickers: tracking 2
I/flutter ( 8918): tickers))
I/flutter ( 8918): The widget which was currently being built when the
offending call was made was:
I/flutter ( 8918): FutureBuilder<dynamic>(dirty, state: _
FutureBuilderState<dynamic>#9d4af)
I/flutter ( 8918):
I/flutter ( 8918): When the exception was thrown, this was the stack:
I/flutter ( 8918): #0 Element.markNeedsBuild.<anonymous closure>
(package:flutter/src/widgets/framework.dart:3472:11)
I/flutter ( 8918): #1 Element.markNeedsBuild
(package:flutter/src/widgets/framework.dart:3498:6)
I/flutter ( 8918): #2 State.setState
(package:flutter/src/widgets/framework.dart:1141:14)
I/flutter ( 8918): #3 ScaffoldState.showSnackBar
(package:flutter/src/material/scaffold.dart:1110:5)
I/flutter ( 8918): #4 MyApp._showSnackBar
I/flutter ( 8918): #5 MyApp.build.<anonymous closure>
I/flutter ( 8918): #6 _FutureBuilderState.build
(package:flutter/src/widgets/async.dart)
I/flutter ( 8918): #7 StatefulElement.build
(package:flutter/src/widgets/framework.dart:3766:27)
I/flutter ( 8918): #8 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:3678:15)
I/flutter ( 8918): #9 Element.rebuild
(package:flutter/src/widgets/framework.dart:3531:5)
I/flutter ( 8918): #10 BuildOwner.buildScope
(package:flutter/src/widgets/framework.dart:2273:33)
I/flutter ( 8918): #11
我的目的是在获取数据之前显示加载微调器,一旦获取数据,则显示SnackBar.那我该怎么做才能解决这个问题呢? Login.main
是从数据库中获取数据的功能.
My purpose is that it shows a loading spinner before it gets the data, and once it got the data, it shows a SnackBar. So what should I do to fix the problem? Login.main
is a function that GET data from the database.
推荐答案
FutureBuilder
或StreamBuilder
应该仅用于构建窗口小部件,而不用于执行导航之类的逻辑.改为使用initState
喜欢
FutureBuilder
or StreamBuilder
should only used to build widgets, not to execute logic like navigation. Use instead initState
like
@override
void initState() {
super.initState();
_checkLogin();
}
Future<void> _checkLogin() async {
try {
var data = await login.main();
setState(() {
_waitForLogin = false;
});
_showSnackBar(data);
} catch(e) {
setState(() {
_waitForLogin = false;
_loginErrorMessage = '$e';
});
}
}
bool _isWaitForLogin = true;
String _loginErrorMessage;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Center(
child: _isWaitForLogin ? CircularProgressIndicator() :
(_loginErrorMessage != null ? Text(_loginErrorMessage : Container())
),
),
);
}
这篇关于当我尝试在构建器中显示SnackBar时出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!