Flutter: Object was given an infinite size during layout

冷暖自知 提交于 2020-12-08 07:05:02

问题


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:


回答1:


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


来源:https://stackoverflow.com/questions/60058946/flutter-object-was-given-an-infinite-size-during-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!