TextField all'interno di Row provoca un'eccezione di layout: impossibile calcolare la dimensione


147

Ricevo un'eccezione di rendering che non capisco come risolvere. Sto tentando di creare una colonna con 3 righe.

Fila [Immagine]

Riga [TextField]

Riga [pulsanti]

Ecco il mio codice per creare il contenitore:

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

e il mio codice buildAppEntryRow per il contenitore di testo

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

Quando corro ottengo la seguente eccezione:

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)

Se cambio buildAppEntryRow invece solo in un campo di testo come questo

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

Non ricevo più l'eccezione. Cosa mi manca con l'implementazione di Row che sta causando l'impossibilità di calcolare la dimensione di quella riga?

Risposte:


318

(Suppongo che tu stia usando un Rowperché vuoi mettere altri widget accanto a TextFieldin futuro.)

Il Rowwidget vuole determinare la dimensione intrinseca dei suoi figli non flessibili in modo da sapere quanto spazio ha lasciato per quelli flessibili. Tuttavia, TextFieldnon ha una larghezza intrinseca; sa solo come dimensionare l'intera larghezza del suo contenitore padre. Prova a racchiuderlo in a Flexibleo Expandeda dire Rowche ti aspetti che occupi lo TextFieldspazio rimanente:

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

3
Questo non dovrebbe essere su Flutter Doc da qualche parte?
stt106,

1
@ stt106 è -> flutter.io/docs/development/ui/layout/box-constraints Ma sono d'accordo, non è facile da trovare. Né rendono la soluzione ovvia come ha fatto Collin Jackson sopra.
Rap

L'uso di questo metodo si interrompe mainAxisAlignmentper il widget Row. Con due widget di testo non c'è problema ma con un widget di testo e un widget Campo di testo in Flexibleesso contenuto viene allineato a sinistra senza spaziatura.
Hasen,

Posso chiederti di dare un'occhiata a una domanda relativa a Flutter qui: stackoverflow.com/questions/60565658/… ?
Istiaque Ahmed,

30

Questo errore viene visualizzato perché si TextFieldespande in direzione orizzontale, così come il Row, quindi è necessario limitare la larghezza del TextField, ci sono molti modi per farlo.

  1. Uso Expanded

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

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
  3. Avvolgilo Containero oppure SizedBoxforniscilowidth

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

2
Questa raccomandazione è così utile. Quando ne hai multipli TextFieldin una riga.
Ben

11

dovresti usare Flexible per usare un campo di testo all'interno di una riga.

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


              ],//widget
            ),//row

Penso che non ti serva Container, puoi usare Flexibledirettamente.
Felipe Augusto

6

La soluzione è racchiudere Text()uno dei seguenti widget: O Expandedoppure Flexible. Quindi, il tuo codice usando Expanded sarà come:

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

5

Come ha detto @Asif Shiraz, ho avuto lo stesso problema e ho risolto questo problema avvolgendo Column in a Flexible, qui in questo modo ,,

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

Una soluzione semplice è avvolgere il tuo Text()interno a Container(). Quindi, il tuo codice sarà come:

Container(
      child: TextField()
)

Qui ottieni anche l'attributo larghezza e altezza di un contenitore per regolare l'aspetto del tuo campo di testo. Non è necessario utilizzarlo Flexiblese si avvolge il campo di testo all'interno di un contenitore.


1
non risolve la domanda senza aggiungerewidth: n
user3249027
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.