Tomaszeek
Tomaszeek

Reputation: 523

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

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.

Upvotes: 48

Views: 62596

Answers (18)

Lahiru Chandima
Lahiru Chandima

Reputation: 24128

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

Upvotes: 0

Bob Abi
Bob Abi

Reputation: 1

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.

Upvotes: 0

Yoko Hailemariam
Yoko Hailemariam

Reputation: 47

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

Upvotes: 1

JAY G S
JAY G S

Reputation: 11

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

  1. Uninstalled the application from the device
  2. flutter clean
  3. flutter run

Upvotes: 0

Praveen G
Praveen G

Reputation: 984

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.

Upvotes: 27

John Kinyanjui
John Kinyanjui

Reputation: 1214

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

Upvotes: 55

Ali Murtaza
Ali Murtaza

Reputation: 550

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.

Upvotes: 1

Ahmed El-Atab
Ahmed El-Atab

Reputation: 681

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!

Upvotes: 0

Promlert Lovichit
Promlert Lovichit

Reputation: 181

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

Upvotes: -1

Zayd Sahdi
Zayd Sahdi

Reputation: 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.

Upvotes: -1

Andrey Gordeev
Andrey Gordeev

Reputation: 32529

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://stackoverflow.com/a/66258147/1321917
    _backButtonDispatcher.takePriority();
    return Router(
      routerDelegate: _routerDelegate,
      backButtonDispatcher: _backButtonDispatcher,
    );
  }
}

Upvotes: 0

Phill Alexakis
Phill Alexakis

Reputation: 1499

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

Upvotes: 4

emkarachchi
emkarachchi

Reputation: 802

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

Upvotes: 0

M&#225;rcio Valim
M&#225;rcio Valim

Reputation: 3535

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.

Upvotes: 0

user13209263
user13209263

Reputation: 31

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.

Upvotes: 3

Jiten Basnet
Jiten Basnet

Reputation: 1820

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

Upvotes: 0

Dimitri
Dimitri

Reputation: 408

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.

Upvotes: 31

Eduardo Pagliuca
Eduardo Pagliuca

Reputation: 21

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.

Upvotes: 2

Related Questions