从 Firebase Cloud 加载帖子时显示错误.. 我在我的应用程序中使用提供程序
setState() or markNeedsBuild() called during build.
详细错误
════════ Exception caught by foundation library ════════════════════════════════
The following assertion was thrown while dispatching notifications for PostFunctions:
setState() or markNeedsBuild() called during build.
This _InheritedProviderScope<PostFunctions> 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.
我加载帖子时的代码..
Widget feedBody(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.orderBy('time', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: SizedBox(
height: 200.0,
width: 200.0,
child: Lottie.asset('assets/animations/loading.json'),
),
);
} else {
return loadPosts(context, snapshot);
}
},
),
height: MediaQuery.of(context).size.height * 0.80,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: constantColors.darkColor.withOpacity(0.6),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(18.0),
topRight: Radius.circular(18.0),
),
),
),
),
);
}
我的加载邮政编码
Widget loadPosts(
BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
return ListView(
children: snapshot.data.docs.map((DocumentSnapshot documentSnapshot) {
Provider.of<PostFunctions>(context, listen: false)
.showTimeAgo(documentSnapshot.data()['time']);
return Container(
height: MediaQuery.of(context).size.height * 0.62,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(
top: 8.0,
left: 8.0,
),
child: Row(
children: [
GestureDetector(
onTap: () {
if (documentSnapshot.data()['useruid'] !=
Provider.of<Authenticationss>(context, listen: false)
.getUserUid) {
Navigator.pushReplacement(
context,
PageTransition(
child: AltProfile(
userUid: documentSnapshot.data()['useruid'],
),
type: PageTransitionType.bottomToTop,
),
);
}
},
child: CircleAvatar(
backgroundColor: constantColors.blueGreyColor,
radius: 20.0,
backgroundImage:
NetworkImage(documentSnapshot.data()['userimage']),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Container(
width: MediaQuery.of(context).size.width * 0.6,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: Text(
documentSnapshot.data()['caption'],
style: TextStyle(
color: constantColors.greenColor,
fontWeight: FontWeight.bold,
fontSize: 16.0),
),
),
Container(
child: RichText(
text: TextSpan(
text: documentSnapshot.data()['username'],
style: TextStyle(
color: constantColors.blueColor,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
children: <TextSpan>[
TextSpan(
text:
' , ${Provider.of<PostFunctions>(context, listen: false).getImageTimePosted.toString()}',
style: TextStyle(
color: constantColors.lightColor
.withOpacity(0.8),
),
)
],
),
),
),
],
),
),
),
Container(
width: MediaQuery.of(context).size.width * .2,
height: MediaQuery.of(context).size.height * 0.05,
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('awards')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView(
scrollDirection: Axis.horizontal,
children: snapshot.data.docs
.map((DocumentSnapshot documentSnapshot) {
return Container(
height: 30.0,
width: 30.0,
child: Image.network(
documentSnapshot.data()['award']),
);
}).toList(),
);
}
},
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
height: MediaQuery.of(context).size.height * 0.45,
width: MediaQuery.of(context).size.width,
child: FittedBox(
child: Image.network(
documentSnapshot.data()['postimage'],
scale: 2,
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Padding(
padding: const EdgeInsets.only(left: 21.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 80.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onLongPress: () {
Provider.of<PostFunctions>(context, listen: false)
.showLikes(
context,
documentSnapshot.data()['caption'],
);
},
onTap: () {
print('adding like');
Provider.of<PostFunctions>(context, listen: false)
.addLike(
context,
documentSnapshot.data()['caption'],
Provider.of<Authenticationss>(context,
listen: false)
.userUid);
},
child: Icon(
FontAwesomeIcons.heart,
color: constantColors.redColor,
size: 22.0,
),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('likes')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
snapshot.data.docs.length.toString(),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
);
}
},
)
],
),
),
Container(
width: 80.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
Provider.of<PostFunctions>(context, listen: false)
.shotCommentSheets(context, documentSnapshot,
documentSnapshot.data()['caption']);
},
child: Icon(
FontAwesomeIcons.comment,
color: constantColors.blueColor,
size: 22.0,
),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('comments')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
snapshot.data.docs.length.toString(),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
);
}
},
)
],
),
),
Container(
width: 80.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onLongPress: () {
Provider.of<PostFunctions>(context, listen: false)
.showAwardPresenter(context,
documentSnapshot.data()['caption']);
},
onTap: () {
Provider.of<PostFunctions>(context, listen: false)
.showReward(context,
documentSnapshot.data()['caption']);
},
child: Icon(
FontAwesomeIcons.award,
color: constantColors.yellowColor,
size: 22.0,
),
),
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('posts')
.doc(documentSnapshot.data()['caption'])
.collection('awards')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
snapshot.data.docs.length.toString(),
style: TextStyle(
color: constantColors.whiteColor,
fontWeight: FontWeight.bold,
fontSize: 18.0,
),
),
);
}
},
)
],
),
),
Spacer(),
Provider.of<Authenticationss>(context, listen: false)
.getUserUid ==
documentSnapshot.data()['useruid']
? IconButton(
icon: Icon(
EvaIcons.moreVertical,
color: constantColors.whiteColor,
),
onPressed: () {
Provider.of<PostFunctions>(context, listen: false)
.showPostOptions(context,
documentSnapshot.data()['caption']);
},
)
: Container(
height: 0.0,
width: 0.0,
),
],
),
),
),
],
),
);
}).toList());
}
}
答案 0 :(得分:2)
正如错误所描述的,甚至在构建函数完成之前就调用了 setState。
当此异常在调试或本地发布模式下发生时,您可能不会在 UI 中看到任何问题。但是像这样的例外会显示灰屏或其他东西,而不是谷歌播放版本等中所需的小部件。
这意味着即使初始小部件已经加载,您也尝试刷新页面。
为了防止在构建方法已经在进行期间调用 setState,您可以在调用 setState 之前检查您的初始小部件是否正确安装。为此,只需通过这样的 if 语句包装您的 setState :
if(mounted){
setState((){
});
}
还有一个方法 with 在 build 方法完成后被调用。按照这个问题了解更多信息:Is there any callback to tell me when "build" function is done in Flutter?