我得到一个渲染异常,我不知道如何修复。我试图创建一个有3行的列。

行[图片]

行[TextField]

行(按钮)

下面是我构建容器的代码:

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实现中遗漏了什么,导致它无法计算该行的大小?


(我假设你正在使用一个行,因为你想把其他小部件旁边的TextField在未来。)

Row小部件希望确定其非柔性子部件的固有大小,以便知道为柔性子部件留下了多少空间。然而,TextField没有一个内在的宽度;它只知道如何将自己的大小调整到父容器的完整宽度。尝试将它包装在一个灵活或扩展,告诉行,你期望TextField占用剩余的空间:

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

你应该使用Flexible来在一行中使用Textfield。

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


              ],//widget
            ),//row

一个简单的解决方案是将Text()包装在Container()中。 所以,你的代码会是这样的:

Container(
      child: TextField()
)

在这里,您还可以获得容器的宽度和高度属性,以调整文本字段的外观。如果你在容器中包装文本字段,就不需要使用Flexible。


正如@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,
          ),
        ));
  }
}

解决方案是将你的Text()包装在以下小部件之一: 扩展的或灵活的。因此,使用Expanded的代码将像这样:

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

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

使用扩展 行( 孩子们:<部件> ( 扩展(孩子:文本域()), OtherWidget (), ), ) 使用灵活 行( 孩子们:<部件> ( 灵活(孩子:文本域()), OtherWidget (), ), ) 将其包装在容器或大小盒中,并提供宽度 行( 孩子们:<部件> ( 大小框(宽度:100,子:TextField()), OtherWidget (), ), )


我也有同样的问题。

如果你愿意,你可以使用表格小部件来避免TextField的这种问题


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))),
            ),
          ),
        ),
      ],
    ),

如果你想让你的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对这个小部件的描述。

创建一个小部件,将其子部件的大小设置为子部件的固有宽度。 这门课比较贵。尽可能避免使用它。


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

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

一个TextField的InputDecoration可以导致一个无限宽度的问题,当放在一行。Flutter在InputDecoration约束属性文档中解释了这一点:

通常,decorator将填充给定的水平空间. ...如果为空,则环境主题数据。inputDecorationTheme inputDecorationTheme。将使用约束。如果该值为空,则装饰器将根据文本大小用默认高度填充可用宽度。

因此,好消息是,TextField的宽度可以在不使用扩展等周边小部件的情况下受到约束。简单地为TextField小部件使用的InputDecoration的constraints参数提供一个BoxConstraints实例:

const TextField(
  decoration: InputDecoration(
    constraints: BoxConstraints.tightFor(
          width: 200,
    ),
  ),
)

正如上面的Flutter文档中提到的,一组约束可以一次应用到几个小部件上,方法是使用Theme和ThemeData, ThemeData指定InputDecorationTheme,其中包含Theme的后代小部件要继承和使用的所需约束。