TextField innerhalb der Zeile verursacht eine Layoutausnahme: Die Größe kann nicht berechnet werden


147

Ich erhalte eine Rendering-Ausnahme, deren Behebung ich nicht verstehe. Ich versuche eine Spalte mit 3 Zeilen zu erstellen.

Zeile [Bild]

Zeile [TextField]

Zeile [Schaltflächen]

Hier ist mein Code zum Erstellen des Containers:

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;
  }

und mein buildAppEntryRow-Code für den Textcontainer

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

Wenn ich laufe, erhalte ich die folgende Ausnahme:

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)

Wenn ich buildAppEntryRow stattdessen in ein TextField ändere

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

Ich bekomme keine Ausnahme mehr. Was fehlt mir bei der Zeilenimplementierung, die dazu führt, dass die Größe dieser Zeile nicht berechnet werden kann?

Antworten:


316

(Ich gehe davon aus, dass Sie ein verwenden, Rowweil Sie TextFieldin Zukunft andere Widgets neben das stellen möchten .)

Das RowWidget möchte die Größe seiner nicht flexiblen Kinder bestimmen, damit es weiß, wie viel Platz es für die flexiblen Kinder übrig hat. Hat TextFieldjedoch keine intrinsische Breite; Es weiß nur, wie es sich auf die volle Breite seines übergeordneten Containers skaliert. Versuchen Sie, es in ein Flexibleoder Expandedzu wickeln , um zu sagen, Rowdass Sie erwarten TextField, dass das den verbleibenden Platz einnimmt:

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

3
Sollte das nicht irgendwo auf Flatterdokument sein?
stt106

1
@ stt106 es ist -> flutter.io/docs/development/ui/layout/box-constraints Aber ich stimme zu, es ist nicht leicht zu finden. Sie machen die Lösung auch nicht so offensichtlich wie Collin Jackson oben.
Rap

Die Verwendung dieser Methode unterbricht mainAxisAlignmentdas Zeilen-Widget. Bei zwei Text-Widgets gibt es kein Problem, aber bei einem Text-Widget und einem darin enthaltenen Textfeld-Widget wird Flexiblees ohne Abstand nach links ausgerichtet.
Hasen

Darf ich Sie bitten, sich hier eine Frage zu Flutter anzusehen: stackoverflow.com/questions/60565658/… ?
Istiaque Ahmed

30

Sie erhalten diesen Fehler, weil er TextFieldsich in horizontaler Richtung ausdehnt, ebenso wie der Row. Daher müssen wir die Breite des einschränken. TextFieldEs gibt viele Möglichkeiten, dies zu tun.

  1. Verwenden Expanded

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

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
  3. Wickeln Sie es in Containeroder SizedBoxund sorgen Sie dafürwidth

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

2
Diese Empfehlung ist so nützlich. Wenn Sie mehrere TextFieldin einer Reihe haben.
Ben

11

Sie sollten Flexible verwenden, um ein Textfeld innerhalb einer Zeile zu verwenden.

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


              ],//widget
            ),//row

Ich denke du brauchst das nicht Container, du kannst das Flexibledirekt benutzen .
Felipe Augusto

6

Die Lösung besteht darin, Text()eines der folgenden Widgets einzuschließen: Entweder Expandedoder Flexible. Ihr Code mit Expanded lautet also wie folgt:

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

5

Wie @Asif Shiraz erwähnte, hatte ich das gleiche Problem und löste dieses Problem, indem ich Column in a Flexible einwickelte.

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

Eine einfache Lösung besteht darin, Ihr Text()Inneres einzuwickeln Container(). Ihr Code lautet also wie folgt:

Container(
      child: TextField()
)

Hier erhalten Sie auch das Attribut width und height eines Containers, um das Erscheinungsbild Ihres Textfelds anzupassen. Keine Notwendigkeit zu verwenden, Flexiblewenn Sie Ihr Textfeld in einen Container einschließen.


1
löst die Frage nicht ohne hinzuzufügenwidth: n
user3249027
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.