Pole TextField w wierszu powoduje wyjątek układu: nie można obliczyć rozmiaru

147

Otrzymuję wyjątek dotyczący renderowania, którego nie rozumiem, jak to naprawić. Próbuję utworzyć kolumnę, która ma 3 wiersze.

Wiersz [obraz]

Wiersz [TextField]

Wiersz [przyciski]

Oto mój kod do zbudowania kontenera:

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

i mój kod buildAppEntryRow dla kontenera tekstu

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

Kiedy biegam, pojawia się następujący wyjątek:

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)

Jeśli zamiast tego zmienię buildAppEntryRow na tylko TextField

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

Nie mam już wyjątku. Czego brakuje mi w implementacji Row, co powoduje, że nie jest w stanie obliczyć rozmiaru tego wiersza?

Matthew Smith
źródło

Odpowiedzi:

318

(Zakładam, że używasz a, Rowponieważ chcesz umieścić inne widżety obok TextFieldw przyszłości).

RowWidget chce ustalić wewnętrzną wielkość jego nieelastycznych dzieci, więc wie, jak dużo miejsca, że nie wyjechał do elastycznych nich. Jednak TextFieldnie ma wewnętrznej szerokości; wie tylko, jak dopasować się do pełnej szerokości swojego kontenera nadrzędnego. Spróbuj zawinąć go w Flexiblelub, Expandedaby powiedzieć Row, że spodziewasz się, że TextFieldzajmie pozostałe miejsce:

      new Row(
        children: <Widget>[
          new Flexible(
            child: new TextField(
              decoration: const InputDecoration(helperText: "Enter App ID"),
              style: Theme.of(context).textTheme.body1,
            ),
          ),
        ],
      ),
Collin Jackson
źródło
3
Czy to nie powinno być gdzieś na flutter Doc?
stt106
1
@ stt106 to jest -> flutter.io/docs/development/ui/layout/box-constraints Ale zgadzam się, nie jest to łatwe do znalezienia. Nie sprawiają też, że rozwiązanie jest tak oczywiste, jak zrobił to powyżej Collin Jackson.
Rap
Użycie tej metody przerywa mainAxisAlignmentdziałanie widżetu Wiersz. Z dwoma widżetami tekstowymi nie ma problemu, ale z widżetem tekstowym i zawartym w Flexiblenim widżetem Pole tekstowe jest wyrównany do lewej bez odstępów.
Hasen,
Czy mogę prosić o przyjrzenie się pytaniu związanemu z Flutter tutaj: stackoverflow.com/questions/60565658/… ?
Istiaque Ahmed
30

Otrzymujesz ten błąd, ponieważ TextFieldrozszerza się w kierunku poziomym, podobnie jak Row, więc musimy ograniczyć szerokość TextField, jest na to wiele sposobów.

  1. Posługiwać się Expanded

     Row(
      children: <Widget>[
        Expanded(child: TextField()),
        OtherWidget(),
      ],
    )
    
  2. Posługiwać się Flexible

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
    
  3. Owiń go Containerlub SizedBoxi podajwidth

    Row(
      children: <Widget>[
        SizedBox(width: 100, child: TextField()),
        OtherWidget(),
      ],
    )       
    
CopsOnRoad
źródło
2
Ta rekomendacja jest bardzo przydatna. Kiedy masz wiele TextFieldw jednym rzędzie.
Ben,
11

aby użyć pola tekstowego wewnątrz wiersza, należy użyć opcji Elastyczny.

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


              ],//widget
            ),//row
Ajit Paul
źródło
Myślę, że nie potrzebujesz Container, możesz użyć Flexiblebezpośrednio.
Felipe Augusto
6

Rozwiązaniem jest umieszczenie Text()wewnątrz jednego z następujących widżetów: Albo Expandedalbo Flexible. Tak więc Twój kod używający Expanded będzie wyglądał następująco:

Expanded(
           child: TextField(
             decoration: InputDecoration(
               hintText: "Demo Text",
               hintStyle: TextStyle(fontWeight: FontWeight.w300, color: Colors.red)
              ),
           ),
        ),
AAEM
źródło
5

Jak wspomniał @Asif Shiraz, miałem ten sam problem i rozwiązałem go, zawijając kolumnę w elastyczny, tutaj w ten sposób,

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,
          ),
        ));
  }
}
Shahzad Akram
źródło
0

Prostym rozwiązaniem jest owinięcie Text()wewnątrz pliku Container(). Twój kod będzie więc wyglądał następująco:

Container(
      child: TextField()
)

Tutaj możesz również uzyskać atrybut szerokości i wysokości kontenera, aby dostosować wygląd i styl pola tekstowego. Nie ma potrzeby używania, Flexiblejeśli zawijasz pole tekstowe wewnątrz kontenera.

vs_lala
źródło
1
nie rozwiązuje pytania bez dodaniawidth: n
user3249027