Row内的TextField导致布局异常:无法计算大小

Mat*_*ith 94 dart flutter

我得到一个渲染异常,我不明白如何修复.我正在尝试创建一个包含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;
  }
Run Code Online (Sandbox Code Playgroud)

和我的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,
        )
      ],
    );
  }
Run Code Online (Sandbox Code Playgroud)

当我运行时,我得到以下异常:

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)
Run Code Online (Sandbox Code Playgroud)

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

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

我不再得到例外.我在Row实现中遗漏了什么导致它无法计算该行的大小?

Col*_*son 214

(我假设您正在使用a,Row因为您希望TextField将来放置其他小部件.)

Row部件要确定其不灵活的儿童的固有大小,所以它知道它已经离开了灵活的人多少空间.但是,TextField没有固有的宽度; 它只知道如何将自身大小调整到其父容器的整个宽度.尝试将其包装在一个Flexible或者Expanded告诉Row你,你期望TextField占用剩余的空间:

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

  • 这难道不是在扑扑文档的某个地方吗? (2认同)

小智 8

您应该使用Flexible在行内使用Textfield。

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


              ],//widget
            ),//row
Run Code Online (Sandbox Code Playgroud)


小智 7

InputDecoration当将 a放入 a 内部时,可能TextField会导致无限宽度问题Row。Flutter 在InputDecoration 约束属性文档中解释了这一点:

通常,装饰器将填充给定的水平空间。...如果为 null,则将使用环境ThemeData.inputDecorationTheme变量。如果为空,则装饰器将根据文本大小使用默认高度填充可用宽度。InputDecorationTheme.constraints

因此,好消息是 a 的宽度TextField可以在不使用周围小部件(如 )的情况下受到限制Expanded。只需BoxConstraints向小部件使用constraints的参数提供一个实例:InputDecorationTextField

const TextField(
  decoration: InputDecoration(
    constraints: BoxConstraints.tightFor(
          width: 200,
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

Theme正如上面 Flutter 文档中提到的,通过使用和 a可以将一组约束同时应用于多个小部件,ThemeData该 指定和 的后代小部件继承和使用InputDecorationTheme所需的约束。Theme


Sha*_*ram 6

正如@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,
          ),
        ));
  }
}
Run Code Online (Sandbox Code Playgroud)


AAE*_*AEM 6

解决的办法是你的包裹Text()下部件的内部:要么ExpandedFlexible。因此,您使用 Expanded 的代码将类似于:

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


Cop*_*oad 6

您会收到此错误,因为TextField会在水平方向扩展,也会这样做Row,因此我们需要限制的宽度TextField,有很多方法可以做到。

  1. 使用 Expanded

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

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
    
    Run Code Online (Sandbox Code Playgroud)
  3. 将其包装在Container或中SizedBox并提供width

    Row(
      children: <Widget>[
        SizedBox(width: 100, child: TextField()),
        OtherWidget(),
      ],
    )       
    
    Run Code Online (Sandbox Code Playgroud)

  • 这个推荐太有用了。当一行中有多个“TextField”时。 (4认同)
  • 当父窗口小部件宽度未硬编码时,“扩展”和“灵活”选项不起作用 (2认同)