Row内のTextFieldによりレイアウト例外が発生:サイズを計算できません


147

修正方法がわからないレンダリング例外が発生します。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,
    );
  }

私はもう例外を受けません。行のサイズを計算できない原因となっている行の実装で何が欠けていますか?

回答:


318

(将来的にはの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,
            ),
          ),
        ],
      ),

3
これはどこかのフラッタードキュメントにあるべきではありませんか?
stt106

1
@ stt106それは-> flutter.io/docs/development/ui/layout/box-constraintsしかし、私は同意する、それを見つけるのは簡単ではない。また、Collin Jacksonが上で行ったように、ソリューションを明白にするものでもありません。
ラップ

このメソッドを使用mainAxisAlignmentすると、行ウィジェットが壊れます。2つのテキストウィジェットがあれば問題はありませんが、テキストウィジェットとFlexibleそれに含まれているテキストフィールドウィジェットは、間隔を空けずに左揃えになります。
Hasen、

ここでFlutter関連の質問をご覧ください。stackoverflow.com/ questions / 60565658 /
Istiaque Ahmed

30

TextField水平方向に拡張し、も拡張するため、このエラーが発生しますRow。したがって、の幅を制限する必要TextFieldがあります。そのための方法はたくさんあります。

  1. 使用する Expanded

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

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
    
  3. Containerまたはで包んでSizedBox提供するwidth

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

2
この推奨事項は非常に便利です。TextField1行に複数ある場合。
ベン

11

行内でテキストフィールドを使用するには、Flexibleを使用する必要があります。

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


              ],//widget
            ),//row

は必要ないと思います。直接Container使用できますFlexible
フェリペアウグスト

6

解決策はText()、次のウィジェットのいずれかを内側にラップすることです:ExpandedまたはFlexible。したがって、Expandedを使用するコードは次のようになります。

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

5

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

0

簡単な解決策は、Text()内部をラップすることContainer()です。したがって、コードは次のようになります。

Container(
      child: TextField()
)

ここでは、コンテナの幅と高さの属性も取得して、テキストフィールドのルックアンドフィールを調整します。Flexibleコンテナ内でテキストフィールドをラップする場合は使用する必要はありません。


1
追加せずに質問を解決しないwidth: n
user3249027
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.