【问题标题】:TextField inside of Row causes layout exception: Unable to calculate sizeRow 内的 TextField 导致布局异常:无法计算大小
【发布时间】:2018-02-09 16:24:42
【问题描述】:

我遇到了一个我不知道如何修复的渲染异常。我正在尝试创建一个有 3 行的列。

行[图片]

行 [文本字段]

行 [按钮]

这是我构建容器的代码:

Container buildEnterAppContainer(BuildContext context) {
    var container = new Container(
      padding: const EdgeInsets.all(8.0),
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          buildImageRow(context),
          buildAppEntryRow(context),
          buildButtonRow(context)
        ],
      ),
    );
    return container;
  }

以及我的文本容器的 buildAppEntryRow 代码

Widget buildAppEntryRow(BuildContext context) {
    return new Row(
      children: <Widget>[
        new TextField(
          decoration: const InputDecoration(helperText: "Enter App ID"),
          style: Theme.of(context).textTheme.body1,
        )
      ],
    );
  }

运行时出现以下异常:

I/flutter ( 7674): BoxConstraints forces an infinite width.
I/flutter ( 7674): These invalid constraints were provided to RenderStack's layout() function by the following
I/flutter ( 7674): function, which probably computed the invalid constraints in question:
I/flutter ( 7674):   RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:256:13)
I/flutter ( 7674): The offending constraints were:
I/flutter ( 7674):   BoxConstraints(w=Infinity, 0.0<=h<=Infinity)

如果我像这样将 buildAppEntryRow 更改为 TextField

 Widget buildAppEntryRow2(BuildContext context) {
    return new TextField(
      decoration: const InputDecoration(helperText: "Enter App ID"),
      style: Theme.of(context).textTheme.body1,
    );
  }

我不再得到异常。导致它无法计算该行大小的 Row 实现缺少什么?

【问题讨论】:

标签: flutter dart flutter-layout flutter-text flutter-row


【解决方案1】:

(我假设您使用的是Row,因为您希望将来将其他小部件放在TextField 旁边。)

Row 小部件想要确定其非灵活子项的固有大小,以便知道它为灵活子项留出了多少空间。但是,TextField 没有固有宽度;它只知道如何将自己的大小调整到其父容器的全宽。尝试将其包装在 FlexibleExpanded 中,以告诉 Row 您希望 TextField 占用剩余空间:

      new Row(
        children: <Widget>[
          new Flexible(
            child: new TextField(
              decoration: const InputDecoration(helperText: "Enter App ID"),
              style: Theme.of(context).textTheme.body1,
            ),
          ),
        ],
      ),

【讨论】:

  • 这不应该出现在 Flutter Doc 上吗?
  • @stt106 是 --> flutter.io/docs/development/ui/layout/box-constraints 但我同意,这并不容易找到。他们也没有像上面的 Collin Jackson 那样使解决方案显而易见。
  • 使用此方法会破坏 Row 小部件的 mainAxisAlignment。使用两个文本小部件没有问题,但使用 Flexible 中包含的一个文本小部件和一个 Textfield 小部件,它会向左对齐,没有间距。
  • 我可以请您在这里查看一个与 Flutter 相关的问题:stackoverflow.com/questions/60565658/… 吗?
  • 出于某种原因,这个小改动需要 Flutter 热重启(不仅仅是热重载),以使布局异常在我的情况下消失。
【解决方案2】:

你得到这个错误是因为TextField水平方向扩展,Row也是,所以我们需要限制TextField的宽度,有很多方法可以做到。

  1. 使用Expanded

     Row(
      children: <Widget>[
        Expanded(child: TextField()),
        OtherWidget(),
      ],
    )
    
  2. 使用Flexible

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
    
  3. 将其包裹在ContainerSizedBox 中并提供width

    Row(
      children: <Widget>[
        SizedBox(width: 100, child: TextField()),
        OtherWidget(),
      ],
    )       
    

【讨论】:

  • 这个建议很有用。当您在一行中有多个 TextField 时。
  • In Row Flexible 是完美的。 Expanded 具有固定高度,我崩溃验证文本
【解决方案3】:

您应该使用灵活来在一行内使用文本字段。

new Row(
              children: <Widget>[
                new Text("hi there"),
                new Container(
                  child:new Flexible(
                        child: new TextField( ),
                            ),//flexible
                ),//container


              ],//widget
            ),//row

【讨论】:

  • 我认为你不需要Container,你可以直接使用Flexible
【解决方案4】:

正如@Asif Shiraz 提到的,我遇到了同样的问题,并通过将列包装成一个灵活的方式解决了这个问题,就像这样,

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: new Scaffold(
          body: Row(
            children: <Widget>[
              Flexible(
                  child: Column(
                children: <Widget>[
                  Container(
                    child: TextField(),
                  )
                  //container
                ],
              ))
            ],
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
          ),
        ));
  }
}

【讨论】:

    【解决方案5】:

    解决方案是将您的 Text() 包装在以下小部件之一中: ExpandedFlexible。因此,您使用 Expanded 的代码将如下所示:

    Expanded(
               child: TextField(
                 decoration: InputDecoration(
                   hintText: "Demo Text",
                   hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
                  ),
               ),
            ),
    

    【讨论】:

      【解决方案6】:
      Row(
            children: [
              Expanded(
                flex: 1,
                child: Padding(
                  padding: EdgeInsets.only(left: 5.0,right: 5.0),
                  child: TextFormField(
                    controller: commentController,
                    validator: (String value){
                      if(value.isEmpty){
                        // ignore: missing_return
                        return 'Comment cannot be blank.';
                      }
                    },
                    decoration: InputDecoration(
                        labelText: "Comment",
                        labelStyle: TextStyle(
                            fontFamily: 'Montserrat',
                            fontWeight: FontWeight.bold,
                            color: Colors.grey),
                        focusedBorder: UnderlineInputBorder(
                            borderSide: BorderSide(color: Colors.green))),
                  ),
                ),
              ),
            ],
          ),
      

      【讨论】:

        【解决方案7】:

        我遇到了同样的问题。

        如果需要,您可以使用 Table 小部件来避免 TextField

        出现此类问题

        【讨论】:

          【解决方案8】:

          一个简单的解决方案是将Text() 包装在Container() 中。 因此,您的代码将如下所示:

          Container(
                child: TextField()
          )
          

          您还可以在此处获取容器的宽度和高度属性,以调整文本字段的外观。如果您将文本字段包装在容器内,则无需使用 Flexible

          【讨论】:

          • 不加width: n就不能解决问题
          【解决方案9】:

          如果您希望 TextField 根据其内容水平调整自身大小,则可以使用 IntrinsicWidth 小部件包装它。

          Row(
           children: [
              Text("From"),
              SizedBox(width: 10,),
              IntrinsicWidth(child: TextField(
                  textAlignVertical: TextAlignVertical.center,
                  decoration: InputDecoration(
                  hintText:  "Start Date Start Date Start Date",
                  hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
                  border: InputBorder.none,
                ),
              ),),
                      SizedBox(width: 10,),
                      Text("To"),
                      SizedBox(width: 10,),
                      IntrinsicWidth(child:  IntrinsicWidth(child: TextField(
               textAlignVertical: TextAlignVertical.center,
                decoration: InputDecoration(
                  hintText:  "End Date",
                  hintStyle: TextStyle(color: Colour.pBlue, fontSize: 14),
                  border: InputBorder.none,
                ),
              ),)),
                    ],
                  )
          

          但在您的代码中使用它之前,请确保了解 Flutter 对这个小部件的说明。

          创建一个小部件,将其子元素的大小调整为子元素的固有宽度。 这个类比较贵。尽可能避免使用它。

          【讨论】:

            【解决方案10】:

            最好的解决方案是绝对空间值

                    Row(
                      children: <Widget>[
                        SizedBox(
                          width: MediaQuery.of(context).size.width * 0.3, 
                          child: _telephonePrefixInput()
                        ),
                        SizedBox(width: MediaQuery.of(context).size.width * 0.02),
                        Expanded(child: _telephoneInput()),
                      ],
                    ),
            

            【讨论】:

              猜你喜欢
              • 2020-09-06
              • 2011-07-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-07-30
              • 2021-11-08
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多