Flutter渲染索引堆栈对象在布局期间被赋予了无限大小

5

我正在解决这个 DropDownItem 框错误,一切似乎都可以工作,但在加载时弹出黄色越界。尝试了几次但无法解决。以下是我的 Widget 代码。

@override
Widget build(BuildContext context) {
    var _children = <Widget>[
      !_createNew ? _referrerPractice() : _referrerCreate(),
    ];
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
        ),
        body: new Column(
          mainAxisSize: MainAxisSize.max,
          children: _children,
        ));
  }

我将其用作其中一个函数。
Widget _referrerPractice() {
assert(!_createNew);
return new Form(
  key: _formKey2,
  child: new Expanded(
    child: new ListView(
      padding: const EdgeInsets.symmetric(horizontal: 16.0),
      children: <Widget>[
        new InputDecorator(
          decoration: const InputDecoration(
            labelText: 'Referrer Practice',
            hintText: 'Choose Referrer Practice or choose new',
          ),
          isEmpty: _referPractice == null,
          child: new DropdownButton<String>(
            value: _referPractice,
            isDense: true,
            onChanged: (String newValue) {
              setState(() {
                _referPractice = newValue;
              });
            },
            items: practicelist.map((Map value) {
              return new DropdownMenuItem<String>(
                value: value['id'].toString(),
                child: new Text(value['name']),
              );
            }).toList(),
          ),
        ),
        new RaisedButton(
            child: new Text('Start'), onPressed: _startReferrer),
      ],
    ),
  ),
);

看起来在另一个页面上它能够工作,而且我没有使用函数来填充小部件,只是一个常规的窗口部件变量,但似乎应该与结构相同。

你有什么想法?这是一个DropDownButton,但对于其他功能也有一个DropDownButton,并且在生成的页面上也会出现这种情况。

编辑********** 这是可行的代码

final List<String> _allTypeAppt = <String>['Elective OP', 'Hospital Transfer', 'Phone Consult'];

new Form(
      key: _formKey,
      autovalidate: _autovalidate,
      onWillPop: _warnUserAboutInvalidData,
      child: new Expanded(
          child: new ListView(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            children: <Widget>[
              new TextFormField(
                decoration: const InputDecoration(
                  icon: const Icon(Icons.person),
                  hintText: 'First Name?',
                  labelText: 'First Name *',
                ),
                controller: _fnameController,

                onSaved: (String value) { referral.fname = value; },
                validator: _validateName,
              ),

              new TextFormField(
                decoration: const InputDecoration(
                  icon: const Icon(Icons.person),
                  hintText: 'Last Name?',
                  labelText: 'Last Name *',
                ),
                controller: _lnameController,
                onSaved: (String value) { referral.lname = value; },
                validator: _validateName,
              ),

              new _DateTimePicker(
                labelText: 'DOB',
                selectedDate: _fromDate,
                selectDate: (DateTime date) {
                  setState(() {
                    _fromDate = date;
                  });
                },
              ),

              new TextFormField(
                decoration: const InputDecoration(
                    icon: const Icon(Icons.phone),
                    hintText: 'How to contact?',
                    labelText: 'Phone Number *',
                ),
                controller: _phoneController,
                keyboardType: TextInputType.phone,
                onSaved: (String value) { referral.contact = value; },
                validator: _validatePhoneNumber,
                // TextInputFormatters are applied in sequence.
                /*inputFormatters: <TextInputFormatter> [
                  WhitelistingTextInputFormatter.digitsOnly,
                  // Fit the validating format.
                  _phoneNumberFormatter,
                ],*/
              ),

              new TextFormField(
                decoration: const InputDecoration(
                  icon: const Icon(Icons.phone),
                  hintText: 'Alt contact?',
                  labelText: 'Alt Phone Number *',
                ),
                controller: _altPhoneController,
                keyboardType: TextInputType.phone,
                onSaved: (String value) { referral.altcontact = value; },
                validator: _validatePhoneNumber,
                // TextInputFormatters are applied in sequence.
                /*inputFormatters: <TextInputFormatter> [
                  WhitelistingTextInputFormatter.digitsOnly,
                  // Fit the validating format.
                  _phoneNumberFormatter,
                ],*/
              ),

              new TextFormField(
                decoration: const InputDecoration(
                  icon: const Icon(Icons.email),
                  hintText: 'Patien Email?',
                  labelText: 'Patient Email *',
                ),
                controller: _emailController,
                onSaved: (String value) { referral.altcontact = value; },
                //validator: _validatePhoneNumber,
                // TextInputFormatters are applied in sequence.
                /*inputFormatters: <TextInputFormatter> [
                  WhitelistingTextInputFormatter.digitsOnly,
                  // Fit the validating format.
                  _phoneNumberFormatter,
                ],*/
              ),

              new TextFormField(
                decoration: const InputDecoration(
                  hintText: 'Tell us about patient',
                  helperText: 'It does not have to be detailed yet',
                  labelText: 'Referral Details',
                ),
                controller: _detailsController,
                maxLines: 5,
              ),

              new InputDecorator(
                decoration: const InputDecoration(
                  labelText: 'Type of Appointment',
                  hintText: 'Choose an Appointment Type',
                ),
                isEmpty: _typeAppt == null,
                child: new DropdownButton<String>(
                  value: _typeAppt,
                  isDense: true,
                  onChanged: (String newValue) {
                    setState(() {
                      _typeAppt = newValue;
                    });
                  },
                  items: _allTypeAppt.map((String value) {
                    return new DropdownMenuItem<String>(
                      value: value,
                      child: new Text(value),
                    );
                  }).toList(),
                ),
              ),

              new RaisedButton(
                child: new Text('Submit Referral'),
                onPressed: _submitData,
              ),

            ],

          )
      )
  ),

1
我不是很明白你的问题,你能否更清楚地表达一下?你遇到了什么错误?它出现在哪里?请尽量清晰地解释问题。问题是什么? - Shady Aziza
你可以展示一下在另一页有效的代码吗? - Shady Aziza
1个回答

1
我已经复现了你的问题,但是不确定为什么你要以这种方式构建布局。你将你的DropDownButton作为InputDecoratorchild属性来使用,这是可以的。然而,它会抛出一个错误,因为DropDownMenuItem溢出了你的InputDecorator。换句话说,你不仅仅是将DopDownButton放在InputDecorator中,还有你的items也在同一个空间内尝试被包含。因此,Flutter不知道如何在InputDecorator所提供的空间内定位items列表。
我真的很困惑你正在尝试构建什么样的布局,你为什么需要一个 Form 和一个 InputDecorator
也许提供一些设计选择的背景信息,我们可以更好地帮助你。
我创建了一个更简单的布局,使用RowTextField小部件,这可能有所帮助。

enter image description here

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _mySelection;
  String _text = "Choose";
   List<Map> _myJson = [
    {"id": "ID 1310012", "name": "Newcommer"}, {"id": "ID 0000TEMP", "name": "Temp"}];

  Widget _children() {
    TextEditingController _controller = new TextEditingController(text: _text);
    return  new Expanded(child: new ListView(
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            children: <Widget>[
              new Container (
        child: new Row(
                  children: <Widget>[
                    new Expanded(
                      child: new TextField(
                        controller: _controller,
                      ),
                    ),
                    new DropdownButton(
                      isDense: true,
                      value: _mySelection,
                      items: _myJson.map((Map map) {
                        return new DropdownMenuItem<String>(
                          value: map["id"],
                          child: new Text(
                            map["name"],
                          ),
                        );
                      }).toList(),
                      onChanged: (String newValue) {
                        setState(() {
                          _mySelection = newValue;
                          _text = newValue;
                        });
                      })
              ],),),
              new RaisedButton(
                  child: new Text('Start'), onPressed: null),

            ]
        ));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("Test")),
      body:  new Column(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
           _children(),
        ],
      ),
    );
  }
}

所以我从flutter的下拉按钮示例中选了一个例子,我使用输入装饰器,因为它允许添加图标、提示文本和标签。工作代码和非工作代码之间唯一的区别是,在非工作代码中,我使用一个小部件函数来填充_children,并使用assert从一个表单切换到另一个表单,而工作代码则有一个静态列表,而不是动态创建的项目列表。所以很奇怪为什么会抛出错误。如果有其他想法可以使其与输入装饰器一起工作,那就太好了,这样我就可以拥有图标等功能... - Robert
你确定在打开刚添加的静态视图的下拉菜单时,控制台上没有出现任何调试错误吗?我的意思是,我知道DropDown可以工作,但你在控制台上看到了什么? - Shady Aziza
我没有收到任何错误信息,我只是再次运行了它,当不工作的程序运行时,我会得到原始错误,但是工作正常的程序没有错误。这就是为什么这毫无意义的原因。 - Robert
我正在进行这个简单的构建,但是我遇到了错误,我不明白它为什么在你那里能够工作。https://dartpad.dartlang.org/51cc48e85041bcd53e2a2cafbc5d4aa8 - Shady Aziza
我想我找到了问题所在。在正常工作的情况下,我有一个已经填充好的列表List = ['xxxx'],而当它不工作时,我从一个空列表xxx=[]开始。当我用默认值填充它时,就不会出现错误。它必须允许知道如何填充它并且可以在没有错误的情况下工作。我猜这在某种程度上是有意义的,感谢你帮助我解决这个问题。 - Robert
显示剩余2条评论

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