flutter - 在构建期间调用 PagewiseLoadController setState() 或 markNeedsBuild()
问题描述
我正在使用flutter_pagewise依赖
class _TagImagesScreenState extends State<TagImagesScreenState> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
...,
PageWiseMemeList(widget.tag)
],
),
);
其中 PageWiseMemeList 的实现方式如下:
class PageWiseMemeList extends StatelessWidget {
final MemeTag tag;
PageWiseMemeList(this.tag);
@override
Widget build(BuildContext context) {
const int PAGESIZE = 10;
return Expanded(
child: PagewiseGridView.count(
pageSize: PAGESIZE,
crossAxisCount: 3,
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
childAspectRatio: 0.555,
padding: EdgeInsets.all(15.0),
itemBuilder: (context, entry, index) =>
_buildMemeGridItem(context, entry),
pageFuture: (pageIndex) =>
this.tag.getMemeFilesFuture(pageIndex * PAGESIZE, PAGESIZE),
),
);
}
最后实现_buildMemeGridItem
Widget _buildMemeGridItem(BuildContext context, DocumentSnapshot document) {
@override
Widget build(BuildContext context) {
MemeFile meme = MemeFile.fromMap(document.data, document.documentID);
return Container(
child: GestureDetector(
onLongPress: () {
MemeShare().shareFile(meme);
},
onTap: () {
Navigator.pushNamed(context, '/image_view',
arguments: ImageViewerArguments(meme));
},
child: FadeInImage(
fit: BoxFit.cover,
placeholder: AssetImage('assets/images/placeholder.jpg'),
image: CacheImage(meme.getGsPath()),
),
),
padding: EdgeInsets.all(2.0),
);
}
}
}
现在,当我尝试执行此代码时,我总是收到以下错误:
════════ Exception caught by foundation library ════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for PagewiseLoadController<dynamic>:
setState() or markNeedsBuild() called during build.
This PagewiseGridView<dynamic> 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.
The widget on which setState() or markNeedsBuild() was called was: PagewiseGridView<dynamic>
state: PagewiseState<dynamic>#0fea7
The widget which was currently being built when the offending call was made was: SliverGrid
delegate: SliverChildBuilderDelegate#1454c(estimated child count: 1)
renderObject: RenderSliverGrid#bc245 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT
When the exception was thrown, this was the stack:
#0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:3896:11)
#1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3911:6)
#2 State.setState (package:flutter/src/widgets/framework.dart:1168:14)
#3 PagewiseState.initState.<anonymous closure> (package:flutter_pagewise/flutter_pagewise.dart:201:39)
#4 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:206:21)
...
The PagewiseLoadController<dynamic> sending notification was: Instance of 'PagewiseLoadController<dynamic>'
当我尝试调试时,我发现 PagewiseState 在 initState() 中有以下代码
@override
void initState() {
super.initState();
if (widget.pageLoadController == null) {
this._controller = PagewiseLoadController<T>(
pageFuture: widget.pageFuture, pageSize: widget.pageSize);
}
this._effectiveController.init();
this._controllerListener = (() => setState(() {}));
this._effectiveController.addListener(this._controllerListener);
}
不确定这是否是问题所在,但可能会有所帮助,第 201 行是:
this._controllerListener = (() => setState(() {}));
解决方案
推荐阅读
- php - Braintree 更新订阅从每年到每月 PHP
- reactjs - React 简单状态管理
- sql-server - SQL Server Preview 需要哪些数据库权限?
- python - 使用 MultiRNNcell 张量流堆叠不同大小的 LSTM 层
- ios - Swift - UIBarButtonItem.customView - 重置为原始状态
- python - 在 Maya 中 CreateRenderNode 并更新自定义 UI
- xml - 通过 XPath 根据条件获取 XML 值
- python - 使用 Python 从 Adobe Analytics (Omniture) API 获取“渠道 (TC)”数据
- file - 如何在没有资源警告的情况下获取 FileLock?
- c++ - C++ 套接字编程无限循环