Flutter: Object was given an infinite size during layout

Rasmus Lian picture Rasmus Lian · Feb 4, 2020 · Viewed 23.6k times · Source

I'm battling an issue where I'm given the error "Object was given an infinite size during layout" and "This probably means that it is a render object that tries to be as big as possible, but it was put inside another render object that allows its children to pick their own size.".

I understand what it means, but not how I can still keep my current widget tree responsive (it renders when running, so for a front-end user there seems to be no problem) while still fixing this issue. Currently I don't set the size of certain things to keep things responsive, and would like to avoid hard coding sizes of widgets if possible.

Any help or pointer in the right direction is greatly appreciated :)

Here's my current code:

    class EditArtikel extends StatefulWidget {
  final String path;

  EditArtikel({this.path});

  @override
  _EditArtikelState createState() => _EditArtikelState(path: path);
}

class _EditArtikelState extends State<EditArtikel> {
  final String path;

  _EditArtikelState({this.path});

  final titleController = TextEditingController();
  final subtitleController = TextEditingController();
  final authorController = TextEditingController();
  final textController = TextEditingController();

  File imageFile;

  List<DropdownMenuItem<dynamic>> dropdownMenuItemFromList() {
    List<DropdownMenuItem<dynamic>> itemsList = [];
    for (var i = 1; i < currentTags.length; i++) {
      itemsList.add(new DropdownMenuItem(
        child: Text(currentTags[i]),
        value: currentTags[i],
      ));
    }
    return itemsList;
  }

  var _selectedValue = "";

  @override
  Widget build(BuildContext context) {
    final isAdmin = Provider.of<bool>(context);
    var pathElements = path.split('/');
    final String artikelID = pathElements[3];
    List<DropdownMenuItem<dynamic>> items = dropdownMenuItemFromList();

    if (isAdmin == true) {
      return LayoutBuilder(
        builder: (context, constraint) {
          return GlobalScaffold(
            body: Container(
              height: constraint.maxHeight,
              child: SingleChildScrollView(
                child: StreamBuilder<ArtikelData>(
                    stream:
                        DatabaseService(pathID: artikelID).artikelByArtikelID,
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        titleController.text == ""
                            ? titleController.text = snapshot.data.title
                            : titleController.text;

                        subtitleController.text == ""
                            ? subtitleController.text = snapshot.data.subtitle
                            : subtitleController.text;

                        authorController.text == ""
                            ? authorController.text = snapshot.data.author
                            : authorController.text;

                        textController.text == ""
                            ? textController.text = snapshot.data.text
                            : textController.text;

                        _selectedValue == ""
                            ? _selectedValue =
                                currentTags.contains(snapshot.data.tags)
                                    ? snapshot.data.tags
                                    : currentTags[1]
                            : _selectedValue = _selectedValue;

                        FirebaseStorageImage fbImage = new FirebaseStorageImage(
                          fileName: artikelID,
                          storageLocation: fbRefArtiklarImages,
                        );

                        return Container(
                          color: primaryColor,
                          padding: EdgeInsets.symmetric(
                              horizontal: 20, vertical: 15),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: <Widget>[
                                  GradientHeading(
                                    large: true,
                                    text: "Redigera artikel",
                                  ),
                                  SizedBox(height: 15),
                                  CustomTextFormField(
                                    labelText: "Rubrik",
                                    controller: titleController,
                                  ),
                                  CustomTextFormField(
                                    labelText: "Underrubrik",
                                    controller: subtitleController,
                                  ),
                                  Padding(
                                    padding: EdgeInsets.only(bottom: 7),
                                    child: DropdownButtonFormField(
                                      decoration: customInputDecoration("Tags"),
                                      value: _selectedValue,
                                      isDense: true,
                                      onChanged: (value) {
                                        setState(() {
                                          _selectedValue = value;
                                        });
                                      },
                                      items: items,
                                    ),
                                  ),
                                  CustomTextFormField(
                                    labelText: "Skriven av",
                                    controller: authorController,
                                  ),
                                  CustomTextFormField(
                                    labelText: "Text",
                                    multiline: true,
                                    controller: textController,
                                  ),
                                  NormalButton(
                                    text: "Ladda upp ny bild",
                                    outlined: true,
                                    outlinedBgColor: primaryColor,
                                    onPressed: () async {
                                      FocusScope.of(context).unfocus();
                                      imageFile = await ChooseImage()
                                          .chooseImageFromGallery();
                                      setState(() {});
                                    },
                                  ),
                                  ConditionalBuilder(
                                    condition: imageFile == null,
                                    ifTrue: NormalButton(
                                      text: "Ta bort originalbild",
                                      shouldOverideColor: true,
                                      overriddenColor: redWarningColor,
                                      onPressed: () async {
                                        FocusScope.of(context).unfocus();
                                        showDialog(
                                          context: context,
                                          barrierDismissible: true,
                                          builder: (_) => AlertDialog(
                                            content: Text(
                                                "Vill du radera originalbilden?"),
                                            actions: <Widget>[
                                              FlatButton(
                                                child: Text("Avbryt"),
                                                onPressed: () {
                                                  Navigator.of(context).pop();
                                                },
                                              ),
                                              FlatButton(
                                                child: Text("Radera"),
                                                onPressed: () async {
                                                  await StorageService()
                                                      .deleteArtikelImageToStorage(
                                                          artikelID);
                                                  setState(() {});
                                                  Navigator.of(context).pop();
                                                },
                                              ),
                                            ],
                                          ),
                                        );
                                      },
                                    ),
                                  ),
                                  ConditionalBuilder(
                                    condition: imageFile != null,
                                    ifTrue: NormalButton(
                                      text: "Ta bort bild",
                                      shouldOverideColor: true,
                                      overriddenColor: redWarningColor,
                                      onPressed: () {
                                        FocusScope.of(context).unfocus();
                                        imageFile = null;
                                        setState(() {});
                                      },
                                    ),
                                  ),
                                  ConditionalBuilder(
                                    condition: imageFile != null,
                                    ifTrue: imageFile != null
                                        ? Image(
                                            image: FileImage(imageFile),
                                          )
                                        : Container(),
                                    ifFalse: fbImage,
                                  ),
                                  SizedBox(height: 40),
                                ],
                              ),
                              NormalButton(
                                text: "Publisera ändringar",
                                onPressed: () async {
                                  if (titleController.text != "" &&
                                      subtitleController.text != "" &&
                                      authorController.text != "" &&
                                      textController.text != "") {
                                    DatabaseService().editArtikel(
                                      artikelID,
                                      titleController.text,
                                      subtitleController.text,
                                      _selectedValue,
                                      authorController.text,
                                      textController.text,
                                      imageFile,
                                    );
                                    Navigator.pop(context);
                                  } else {
                                    showDialog(
                                      context: context,
                                      barrierDismissible: true,
                                      builder: (_) => AlertDialog(
                                        content:
                                            Text("Du måste fylla i alla fält"),
                                        actions: <Widget>[
                                          FlatButton(
                                            child: Text("OK"),
                                            onPressed: () {
                                              Navigator.of(context).pop();
                                            },
                                          )
                                        ],
                                      ),
                                    );
                                  }
                                },
                              ),
                            ],
                          ),
                        );
                      } else {
                        return LoadingWidget();
                      }
                    }),
              ),
            ),
          );
        },
      );
    } else {
      return GlobalScaffold(
        body: Center(
          child: Text("Du har inte tillgång till den här sidan"),
        ),
      );
    }
  }
}

And here's the error log: enter image description here enter image description here

Answer

daniel vofchuk picture daniel vofchuk · Feb 4, 2020

From where I can see, you have the problem because you are inserting the StreamBuilder inside the SingleChildScrollView which has an infinite height to grow, and StreamBuilder asks for his parent's height.

StreamBuilder needs a parent that has a fixed size, so he can understand how much space he has to render his children.

what you need to do is to put the SingleChildScrollView inside a Container with a given size (You can put all the body inside a LayoutBuilder and use the constrains.maxHeight as the height to the container, so SingleChildScrollView knows its size).

like this: (Since I don't have your widgets, I can't run this code... so maybe there are some parentheses missing)

I hope this helps!

return GlobalScaffold(
       body: LayoutBuilder(
         builder: (ctx, constrains){
           return GlobalScaffold(
      body: Container(
        height: constrains.maxHeight,
        child: SingleChildScrollView(
          child: Container(
            padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                GradientHeading(text: "Guider", large: true),
                ConditionalBuilder(
                  condition: isAdmin,
                  ifTrue: Column(
                    children: <Widget>[
                      NormalButton(
                        text: "Skapa ny guide",
                        onPressed: () {
                          Navigator.pushNamed(context, createNewArtikelRoute);
                        },
                      ),
                      NormalButton(
                        text: "Lägg till ny kategori",
                        outlined: true,
                        onPressed: () {},
                      ),
                    ],
                  ),
                ),
                SizedBox(height: 10),
                StreamBuilder<List<GuiderCategoriesData>>(
                  stream: DatabaseService().guiderCategoriesByPopularity,
                  builder: (context, snapshot) {
                    if (snapshot.connectionState == ConnectionState.active) {
                      return GuiderCategories(
                        snapshot: snapshot,
                        numberOfCategories: snapshot.data.length,
                      );
                    } else if (!snapshot.hasData) {
                      return GuiderCategories(
                        hasNoCategories: true,
                      );
                    } else {
                      return LoadingWidget();
                    }
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
  )
  );