android - 颤振应用程序中的“setState() 或 MarkNeedsBuild() 期间调用”错误
问题描述
我是颤振的初学者。当我调用Settings widget
时会发生以下错误。我尝试了从同一问题发布的所有内容,但没有任何改变。当我删除它时,StreamBuilder
它工作正常。但是,如果没有,StreamBuilder
我将无法从 cloud firestore 获取数据并将其显示在设置小部件中。
这是我调用的主屏幕Settings widget
。
body: FlatButton.icon(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Settings()));
},
icon: Icon(Icons.settings),
label: Text('User Profile')),
);
这是设置小部件
import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_firebase_test/screens/services/auth.dart';
import 'package:flutter_firebase_test/shared/loading.dart';
class Settings extends StatefulWidget {
@override
_Settings createState() => _Settings();
}
class _Settings extends State<Settings> {
AuthService _auth = new AuthService();
@override
Widget build(BuildContext context) {
Color randomColor() {
int index = 0;
List colors = [
Colors.red,
Colors.blue,
Colors.green,
Colors.yellow,
Colors.amber,
Colors.deepPurple
];
Random rnd = new Random();
setState(() => index = rnd.nextInt(6));
return colors[index];
}
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('users').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Loading();
} else {
return Scaffold(
body: Container(
padding: EdgeInsets.fromLTRB(30, 80, 30, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Column(
children: [
CircleAvatar(
backgroundColor: randomColor(),
//backgroundImage: AssetImage('assets/avatars/male1.jpg'),
radius: 60,
child: Text(
// TODO: The name will be set later!
"Ali"[0].toUpperCase(),
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 40,
),
),
),
SizedBox(
height: 20,
),
Text("dasdas"),
],
),
),
SizedBox(
height: 30,
),
Divider(
color: Colors.black,
),
SizedBox(
height: 40,
),
Wrap(children: [
Text(
"Name:",
style: TextStyle(
fontSize: 20,
),
),
SizedBox(
width: 20,
),
]),
SizedBox(
height: 40,
),
Wrap(children: [
Text(
"Username:",
style: TextStyle(
fontSize: 20,
),
),
SizedBox(
width: 20,
),
Text(
"User fullname will display here",
style: TextStyle(
fontSize: 20,
),
),
]),
],
),
),
);
}
});
}
}
flutter doctor -v
结果
] Flutter (Channel stable, 1.22.5, on Microsoft Windows [Version 10.0.19042.685], locale en-US)
• Flutter version 1.22.5 at C:\src\flutter
• Framework revision 7891006299 (3 weeks ago), 2020-12-10 11:54:40 -0800
• Engine revision ae90085a84
• Dart version 2.10.4
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
• Android SDK at C:\Users\demir\AppData\Local\Android\sdk
• Platform android-30, build-tools 30.0.2
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.
调试控制台:
The following assertion was thrown building StreamBuilder<QuerySnapshot>(dirty, state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#778da):
setState() or markNeedsBuild() called during build.
This Settings widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
state: _StreamBuilderBaseState<QuerySnapshot, AsyncSnapshot<QuerySnapshot>>#778da
The relevant error-causing widget was
StreamBuilder<QuerySnapshot>
package:flutter_firebase_test/…/home/settings.dart:31
When the exception was thrown, this was the stack
#0 Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:4292
#1 Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4307
#2 State.setState
package:flutter/…/widgets/framework.dart:1264
#3 _Settings.build.randomColor
package:flutter_firebase_test/…/home/settings.dart:27
#4 _Settings.build.<anonymous closure>
package:flutter_firebase_test/…/home/settings.dart:47
...
解决方案
把你randomColor
的方法放在方法之外build
。此外,您不需要调用setState
索引变量,因为它在该方法中是本地的
Color randomColor() {
int index = 0;
List colors = [
Colors.red,
Colors.blue,
Colors.green,
Colors.yellow,
Colors.amber,
Colors.deepPurple
];
Random rnd = new Random();
index = rnd.nextInt(6);
return colors[index];
}
// ...
@override
Widget build(BuildContext context) {
推荐阅读
- javascript - Javascript文件在github页面上不起作用
- c++ - 如何在带有 tensorflow 的 mkl 中使用 libtbb.so
- excel-formula - 在excel中对单元格进行逻辑计数
- css - bootstrap 的 glyphicon 没有表现出来
- android - 寻求栏设置自定义最小值
- android - 我有一个选项卡式活动,它在纵向模式下工作正常,但在横向模式下停止显示数据。并且滑动也不会在标签中完美运行
- php - Paypal PHP Rest API SDK - 现在似乎没有工作
- sql - SQL Server 中 Conc() 的等价物是什么
- awk - 如果我将字段清零,为什么 awk 会执行不同的 OFS 解析?
- c++ - 函数中调用的构造函数的顺序