首页 > 解决方案 > 在构建期间调用 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(() {}));

标签: flutterdart

解决方案


推荐阅读