Flutter错误:每个子元素必须仅布局一次。在构建布局时发生。

44

我正在使用flutter_bloc。

我的代码是这样的:

class Settings extends StatelessWidget {
  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
          title: new Text("SomeApp",style: TextStyle(color: Colors.white)),
          automaticallyImplyLeading: false,
          backgroundColor: myBlue.shade50,

          actions: <Widget>[
            IconButton(
              icon: new Icon(FontAwesomeIcons.download,color:  Colors.white),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => DownloadView()),
                );
              },
            ),
            IconButton(
              icon: new Icon(FontAwesomeIcons.chevronCircleLeft,color:  Colors.white),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MainWindow()),
                );
              },
            ),]
      ),
      body: Container(
        padding: EdgeInsets.symmetric(vertical: 16),
        alignment: Alignment.center,
        child: new BlocBuilder<SettingsBloc, SettingsState>(
          builder: (context, state) {
            if (state is SettingsNotLoaded) {
              return new Center(
                  child: Text(
                    'count1',
                    style: TextStyle(fontSize: 24.0,color: Colors.black),
                  )
              );
            } else if (state is SettingsLoaded) {  
              return new Center(
                  child: Text(
                    'count2',
                    style: TextStyle(fontSize: 24.0,color: Colors.black),
                  )
              );
            }
            else
              {
                return new Center(
                    child: Text(
                      'count3',
                      style: TextStyle(fontSize: 24.0,color: Colors.black),
                    )
                );
              }
          },
        ),

      ),
    );
  }
当我启动应用程序时,我看到的应用栏与我想要的一样,但是我在正文中没有看到任何文本(我应该看到count1、count2或count3中的任何一个),而是出现了错误:“Each child must be laid out exactly once." 错误指向第5行 - return new Scaffold(
当然,我在flutter_bloc页面、https://flutter.dev/docs/development/ui/layout/tutorial、这里以及谷歌上寻找相关信息。

如果您首先删除BlocBuilder会发生什么? - John Joe
如果我使用blocBuilder删除整个bloc模式,只放置文本小部件,一切都可以正常工作。 - Tomaszeek
有没有修复这个问题的方法?我也遇到了这个问题。 - Yura
你调试过它以查看状态的值吗?new是可选的。 - Abhishek Ghaskata
16个回答

53

我刚遇到了同样的问题,我认为这只是Flutter中的一个错误。停止应用程序,然后重新安装它。


31

最近我遇到了相同的错误。

在我的情况下,错误是由两个扩展小部件嵌套引起的。

通过移除父扩展小部件,错误已经消失。


1
谢谢,这解决了我的问题。 - Novak254
人们应该更加重视这个答案,因为这确实是信息试图警告我们的问题,任何有关清理缓存的事情都只是巧合起作用,这条信息准确地警告了您的小部件存在的问题。 - Renan Borges
它只是有效的,上面的评论@Renan Borges,你说得再正确不过了。 - Gokberk Yar
相同的问题,删除我扩展的两个东西就解决了这个问题。 - DomingoMG

25

这不是Flutter的错误,我曾经也面临同样的问题。尽管上述解决方案是正确的,但有时似乎会失败。

请尝试以下命令

flutter clean

flutter pub get

然后再次运行

flutter run

或者,如果你正在使用带有flutter插件的Android Studio

前往 工具 > Flutter > Flutter Clean

然后再次运行应用程序,

将会执行与上述命令相同的操作。

了解Flutter大约一周后,我现在明白,在代码中进行更改(例如,在pubspec.yaml中添加新的依赖项)需要停止应用程序并再次运行。我注意到IDE中的GUI可能会出现问题(我使用的是Android Studio),但是在命令行中使用上述命令效果很好。


3

请尝试以下操作:

  1. 停止模拟。
  2. 打开Android虚拟设备管理器。
  3. 在虚拟设备中选择“操作”。
  4. 点击向下箭头以查看选项。
  5. 点击“擦除数据”。
  6. 重新运行模拟。

这对于Android设备对我有效。


3

如何修复

flutter clean

对我来说运行正常,尽管它可以被复制。

在我的情况下是什么触发了它

这个问题出现在我实现了Streams后。

我猜想通过使用StreamController并对监听该流的任何内容进行更改,再加上返回到WidgetStreamBuilder,会在运行时产生错误。

重现错误的代码:

  Widget passwordField(){
    return StreamBuilder(
      stream: bloc.getPasswordStream,
        builder: (context,snapshot){
          return TextField(
            onChanged: bloc.addPasswordStream,
            obscureText: true,
            decoration: InputDecoration(
                hintText: 'password',
                labelText: 'password',
                errorText: snapshot.error
            ),
          );
        }
     );
  }

例如:
  1. 更改已打开的中的一些代码(例如:流输入验证器)
  2. 保存应用程序(假设模拟器已经打开)
  3. 重现错误


遇到了完全相同的问题。你有没有找到一种方法可以不用每次都运行flutter clean就解决这个问题? - Chirag Bhansali

2

当我进行热重载时,遇到了相同的问题,然后我执行了热重启,问题就解决了。看起来是Flutter的一个bug。


1
在我的情况下,我在initState()上使用了异步等待。移除它可以解决问题。

1

GetX状态管理专用

在我的情况下,我使用GetX包装了一个小部件。现在我只需将其删除并使用Obx来管理状态即可。


是的,伙计,这是个好观点。但如果你使用Obx,像GetBuilder那样就不能很好地工作。 - ahmed mohamed abdulkadir

0

跟踪调试控制台中的日志,在该错误下,您可能会看到一条日志,其中说:

The stack when the error occurred was:
.............
.............
.............

仔细阅读这些行,了解哪些代码是问题所在!


我需要联系你,你能告诉我通过哪个社交媒体可以联系到你吗?谢谢。 - user13408251
您可以通过LinkedIn联系我:https://www.linkedin.com/in/ahmedatab 或者通过电子邮件联系我: atab.ahmad98@gmail.com - Ahmed El-Atab

0
对于任何在iOS模拟器中遇到此错误的人来说,卸载并重新安装应用程序对我有用。这种情况发生在我们过度使用热重载时。
我的Flutter版本:Flutter(渠道主,1.22.0-2.0.pre.66,在Mac OS X 10.15.3 19D76上,区域设置为en-LK),我正在使用Android Studio进行构建。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接