Flutter:底部 sheet 和 TextField/TextFormField

Flutter: Bottom sheet with TextField/TextFormField

在我们的应用程序的一部分中,我希望在 BottomSheet 中有一个简单的表单,就像下面的代码一样。不幸的是,当我输入它时,出现错误

The following assertion was thrown during performLayout(): An InputDecorator, which is typically created by a TextField, cannot have an unbounded width. This happens when the parent widget does not provide a finite width constraint. For example, if the InputDecorator is contained by a Row, then its width must be constrained. An Expanded widget or a SizedBox can be used to constrain the width of the InputDecorator or the TextField that contains it. 'package:flutter/src/material/input_decorator.dart': Failed assertion: line 881 pos 7: 'layoutConstraints.maxWidth < double.infinity'

我实现的代码:

  void _settingModalBottomSheet(context){
    showModalBottomSheet(
        context: context,
        elevation: 8.0,
        builder: (BuildContext bc){
          return Directionality(
            textDirection: TextDirection.rtl,
            child: ConstrainedBox(
              constraints: BoxConstraints(
                minHeight: 250.0
              ),
              child: Container(
                padding: EdgeInsets.fromLTRB(0.0,10.0,0.0,10.0),
                child: new Wrap(
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Center(
                        child: Text(
                          'please fill this form',
                          style: TextStyle(
                            fontSize: 13.0,
                          ),
                        ),
                      ),
                    ),
                    Divider(),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Column(
                          children: <Widget>[
                            Text('item 1'),
                            Container(
                              child: TextField(),
                            )
                          ],
                        ),
                        Column(
                          children: <Widget>[
                            Text('item 2'),
                            Container(
                              child: TextField(),
                            )
                          ],
                        ),

                      ],
                    ),
                  ],
                ),
              ),
            ),
          );
        }
    );
  }

您必须为 TextField 提供特定宽度,只需在 Container 中提供 width 或将 Column 包裹在 Expanded 中。

解决方案 1

Container(
  width: 100, // do it in both Container
  child: TextField(),
),

解决方案 2

Row(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: <Widget>[
    Expanded( // wrap your Column in Expanded
      child: Column(
        children: <Widget>[
          Text('item 1'),
          Container(child: TextField()),
        ],
      ),
    ),
    Expanded( // wrap your Column in Expanded
      child: Column(
        children: <Widget>[
          Text('item 2'),
          Container(child: TextField()),
        ],
      ),
    ),
  ],
),

将您的 TextField 包裹在具有指定高度的列中。

Column(
  width: 100,
  child: TextField()
),

在上面的问题中,Column 试图比 space 更宽,Row(其父级)可以分配给它,从而导致溢出错误。 Column 为什么要这样做?要理解这种布局行为,需要先了解Flutter框架是如何进行布局的:

“为了执行布局,Flutter 在 depth-first 遍历中遍历渲染树,并 从父级向子级传递尺寸约束 ......子级响应 在父对象建立的约束范围内将大小传递给它们的父对象。”

在这种情况下, Row 小部件不会限制其子项的大小,Column 小部件也不会。由于缺少来自其父小部件的约束,第二个文本小部件尝试与它需要显示的所有字符一样宽。 self-determined 文本小部件的宽度随后被 Column 所采用,这与 Row 小部件可以提供的其父级 space 的最大水平宽度冲突。

如何解决?

嗯,您需要确保 Column 不会尝试变得比它可以的更宽。为此,您需要限制其宽度。一种方法是将 Column 包装在 Expanded 小部件中:

可以通过将 TextField 包装在 Expanded 或 Flexible 小部件中来避免该错误。所以相信该列应该是 Expanded:

Row(
    children: [
      Expanded(
      child: Column(
          children: [
            Text('This is the text and there enough to wrap'),
            TextField()
          ]
      ))
    ]
);