Flutter error: Each child must be laid out exactly once. On building layout
Asked Answered
M

18

45

I'm using flutter_bloc.

I've got code like this:

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),
                    )
                );
              }
          },
        ),

      ),
    );
  }

And when starting my app I see the appBar just the way I want, but I do not see any text in body (I should see either count1, count2 or count3), but instead I get the error:

Each child must be laid out exactly once." referring to line 5 - return new Scaffold(

Of course, I looked for info on flutter_bloc page, on https://flutter.dev/docs/development/ui/layout/tutorial ,here and in google as well.

Marileemarilin answered 5/2, 2020 at 13:29 Comment(4)
what happened if you remove the BlocBuilder first?Frication
if i remove whole bloc pattern with blocBuilder and just put text widget everything works fineMarileemarilin
any fix on this? It happened to me tooAutotruck
have you debugged it to see the value of state? new is opetionalUnlive
M
52

I just had the same problem I think its just a bug in flutter. Stop and then reinstall your app

Magnetomotive answered 8/2, 2020 at 11:23 Comment(0)
O
31

Recently I had the same error.

In my case the error was caused by nesting two Expanded Widgets into each other.

The error has gone by removing the parent Expanded Widget.

Oscar answered 16/5, 2020 at 4:13 Comment(4)
Thank you, this fixed my issue alsoMonkshood
People should give more importance to this answer, this is indeed the problem that message tries to warns us up, anything about cleaning the cache up does work only due a concidence, this message PRECISELY warns you about the problem with your widgets.Cila
It just works, the comment above @Renan Borges, you cannot be more right.Differential
The same problem, Deleting the two expanded ones that I had fixes the problem.Pirnot
G
25

It's not a bug from flutter, I had faced the same issue, although the above solution is correct it seems to fail sometimes.

Try the following command

flutter clean

and

flutter pub get

then run again

flutter run

or

alternatively, if you're on Android Studio (flutter plugins enabled)

Go to Tools > Flutter > Flutter Clean

then run the app again, will do the same as the above commands

After being familiar with Flutter for about a week, now I do understand that making changes in code such as adding in a new dependency in pubspec.yaml requires stopping the app and Running again, I did notice that the GUI in the IDE (I use Android Studio) might have some issue, the above commands in the command line works just fine.

Gaggle answered 23/4, 2020 at 12:38 Comment(0)
J
4

How to fix

flutter clean

Works fine for me, although it can be reproduced

What triggers it in my case

This started for me since I implemented Streams in my application.

I'm assuming that by using a StreamController and making a change to what ever listens to that stream it produces the error on runtime, combined with a StreamBuilder that I return to a Widget.

Code that reproduces the error:

  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
            ),
          );
        }
     );
  }

For example:

  1. Changes some code to an already opened stream (ig: stream input validators)
  2. Saves the application (assume the emulator is already opened)
  3. Error reproduced

Jonasjonathan answered 3/12, 2020 at 20:50 Comment(1)
Having the exact same issue. Did you find a way to fix this without doing flutter clean every time?Masquer
W
3

Try the following:

  1. Stop the simulation.
  2. Go to Android virtual device manager.
  3. Go to "Action" in the virtual device.
  4. Click the down arrow to see the option.
  5. Click "wipe data"
  6. Run the simulation again.

It worked with me for Android devices.

Written answered 3/4, 2020 at 9:39 Comment(0)
E
2

I had the same issue when i performed a hot reload, then i performed a hot restart and it went away. Looks like a Flutter bug.

Euton answered 6/5, 2020 at 5:4 Comment(0)
D
1

GetX State Management Specific

In my case, I was wrapping a widget with GetX. I just remove it and used Obx for managing the state.

Daughterinlaw answered 20/11, 2021 at 4:12 Comment(2)
yeah dude the is good point but if you use Obx it's not working well like GetBuilderCockloft
obx works perfectly , as getx document , obx better to use for streams instead of getbuilder @ahmedmohamedabdulkadirIndecorous
M
1

in my case, I used async-await on initState(). removing it fixes the problem

Miche answered 3/2, 2022 at 5:42 Comment(0)
V
0

I recently encountered this problem and I noticed that using hot reload number of times pushes only modifications in my designs or any stored sqlite data.

  1. So In my cases deleting stored data from app. (clearing all the caches) and
  2. running flutter clean worked
Viglione answered 26/6, 2020 at 10:29 Comment(0)
R
0

I was facing the same issue. I did the following:

  1. Uninstalled the application from the device
  2. flutter clean
  3. flutter run
Rhetorical answered 13/9, 2020 at 18:45 Comment(0)
P
0

Try:

  1. stop the program
  2. adb uninstall "$yourPackageName"
  3. flutter clean
  4. run the program again

You can find the name of your package in "android/app/build.gradle" => defaultConfig/applicationId

Obs: Also remember that this will only work if the problem that caused thos error has already been solved.

This worked for me.

Procne answered 16/9, 2020 at 22:0 Comment(0)
T
0

For anyone having this bug in iOS simulator, uninstalling and re-installing the app worked for me. This happens when we use hot reload too much.

My Flutter version : Flutter (Channel master, 1.22.0-2.0.pre.66, on Mac OS X 10.15.3 19D76, locale en-LK) and I'm using android studio to build

Twophase answered 29/10, 2020 at 6:4 Comment(0)
B
0

This error might happen under the following conditions:

  • You use Navigator 2.0
  • You use ChildBackButtonDispatcher
  • You Hot Reload your app
  • You forgot to take priority in build method:
class _HomeState extends State<Home> {
  HomeRouterDelegate _routerDelegate;
  final _state = HomeState();

  ChildBackButtonDispatcher _backButtonDispatcher;

  @override
  void initState() {
    super.initState();
    _routerDelegate = HomeRouterDelegate(_state);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _backButtonDispatcher = Router.of(context)
        .backButtonDispatcher
        .createChildBackButtonDispatcher();
  }

  @override
  Widget build(BuildContext context) {
    // The app will throw an exception 'Each child must be laid out exactly once.'
    // without this line on each Hot Reload
    // https://mcmap.net/q/366673/-flutter-error-each-child-must-be-laid-out-exactly-once-on-building-layout
    _backButtonDispatcher.takePriority();
    return Router(
      routerDelegate: _routerDelegate,
      backButtonDispatcher: _backButtonDispatcher,
    );
  }
}
Banquette answered 18/2, 2021 at 10:32 Comment(0)
V
0

Track the logs in the debug console and under that error, you might see a log saying:

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

Read these lines carefully to know which code is the problem!

Vivyanne answered 25/8, 2021 at 15:55 Comment(2)
i need to call you, could you give me any social media to contact you through, please?Isaacs
You can contact me via LinkedIn: linkedin.com/in/ahmedatab Or by email on: [email protected]Vivyanne
A
0

Widget which using padding should not be parent widget of any builder widget. Remove padding. And wrap widget inside builder with padding or wrap builder with SizedBox or Container or any.

Acquit answered 11/2, 2024 at 20:13 Comment(0)
B
0

In my case, I was calling setState() indirectly inside initState(), leading to the issue. I used following. to fix it.

@override
void initState() {
  super.initState();
  //...
  WidgetsBinding.instance.addPostFrameCallback((_) {
    // call setState() here
  });
}
Balladmonger answered 14/7, 2024 at 4:17 Comment(0)
P
-1
import 'package:flutter/material.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';

void main()=> runApp(BMIcalculatro());

class BMIcalculatro extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(



  theme: ThemeData.dark().copyWith(

    primaryColor: Color(0xFF0A0E21),


    scaffoldBackgroundColor: Color(0xFF0A0E21),

  ),

  home: InputPage(),

) ;

} }



const activColor = Color(0xFF1D1E33);



const inActiveColor = Color(0XFF111328);



enum Gender{




male, female



}



class InputPage extends StatefulWidget {




@override



_InputPageState createState() => _InputPageState();



}



class _InputPageState extends State {



Gender genderSelected;



@override



Widget build(BuildContext context) {




return Scaffold(



    appBar: AppBar(



      title: Text('BMIcalculator'),



      centerTitle: true,



    ),

    body: Column(



      children: [



        Expanded(




          child: Row(



            children: [



              Expanded(




                child: GestureDetector(



                  onTap: () {



                    setState(() {



                      genderSelected=Gender.male;



                    });




                  },



                  child: ReusableCard(





                    colour: genderSelected ==Gender.male ? activColor: inActiveColor,



                    cardChaild: IconrContakt(



                      icone: FontAwesomeIcons.mars,



                      name: "MAIL",



                    ),


                  ),

                ),

              ),

              Expanded(



                child: GestureDetector(



                  onTap: () {




                    setState(() {



                       genderSelected=Gender.female;



                    });

                  },

                  child: ReusableCard(



                    colour: genderSelected==Gender.female ? activColor:inActiveColor,



                    cardChaild: IconrContakt(




                      icone: FontAwesomeIcons.venus,



                      name: "female",

                    ),

                  ),


                ),


              ),

            ],

          ),

        ),

        Expanded(



          child: Expanded(



            child: ReusableCard(



              colour: activColor,


            ),
          ),

        ),
        Expanded(



          child: Row(



            children: [



              Expanded(



                  child: ReusableCard(



                colour: activColor,



              )),

              Expanded(



                child: ReusableCard(



                  colour: activColor,



                ),

              ),

            ],

          ),

        ),

        Container(



          margin: EdgeInsets.only(top: 12),



          decoration: BoxDecoration(



            color: Color(0xFFEB1555),



          ),

          child: Center(



              child: Text(



            'BMI CALCULATOR',



            style: TextStyle(color: Colors.white, fontSize: 20),



          )),

          width: double.infinity,



          height: 80.0,



        )

      ],

    ),

    );

} }



class IconrContakt extends StatelessWidget {



IconrContakt({this.icone, this.name});



final IconData icone;



final String name;



@override



Widget build(BuildContext context) {



return Column(



  mainAxisAlignment: MainAxisAlignment.center,



  children: [



    Icon(



      icone,



      size: 80,



    ),

    SizedBox(



      height: 15,



    ),

    Text(



      name,



      style: TextStyle(fontSize: 18.0),



    )

  ],

);

} }



class ReusableCard extends StatelessWidget {



ReusableCard({@required this.colour, this.cardChaild});



final Color colour;



final Widget cardChaild;



@override



Widget build(BuildContext context) {



return Container(



  child: cardChaild,



  margin: EdgeInsets.all(12.0),



  decoration: BoxDecoration(



    color: colour,



    borderRadius: BorderRadius.circular(10.3),



  ),

);

} }

And here is the error

════════ Exception caught by widgets library ═══════════════════════════════════

'package:flutter/src/widgets/framework.dart': Failed assertion: line 5022 pos 16: >'child

is!'

ParentDataElement': is not true.'

The relevant error-causing widget was Scaffold lib\home.dart:23

════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════

Each child must be laid out exactly once.

The relevant error-causing widget was Scaffold.

Pilgrimage answered 10/2, 2021 at 20:35 Comment(0)
B
-1

I've got this error when referencing widget in the State's constructor:

class MyWidget extends StatefulWidget {
  MyWidget(this.data, {Key? key}) : super(key: key);

  final String data;

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  _MyWidgetState() {
    debugPrint(widget.data); // This line causes error.
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
Bulk answered 22/7, 2021 at 15:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.