TextField dentro de la fila provoca una excepción de diseño: no se puede calcular el tamaño

147

Recibo una excepción de representación que no entiendo cómo solucionarlo. Estoy intentando crear una columna que tiene 3 filas.

Fila [Imagen]

Fila [TextField]

Fila [Botones]

Aquí está mi código para construir el contenedor:

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

y mi código buildAppEntryRow para el contenedor de texto

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

Cuando corro me sale la siguiente excepción:

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)

Si cambio buildAppEntryRow a solo un TextField como este

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

Ya no tengo la excepción. ¿Qué me falta con la implementación de la fila que hace que no pueda calcular el tamaño de esa fila?

Matthew Smith
fuente

Respuestas:

318

(Supongo que estás usando un Rowporque quieres poner otros widgets al lado del TextFielden el futuro).

El Rowwidget quiere determinar el tamaño intrínseco de sus hijos no flexibles para saber cuánto espacio le queda para los flexibles. Sin embargo, TextFieldno tiene un ancho intrínseco; solo sabe cómo dimensionarse al ancho completo de su contenedor principal. Intente envolverlo en Flexibleo Expandedpara decirle Rowque espera TextFieldque ocupe el espacio restante:

      new Row(
        children: <Widget>[
          new Flexible(
            child: new TextField(
              decoration: const InputDecoration(helperText: "Enter App ID"),
              style: Theme.of(context).textTheme.body1,
            ),
          ),
        ],
      ),
Collin Jackson
fuente
3
¿No debería estar esto en flutter doc en alguna parte?
stt106
1
@ stt106 es -> flutter.io/docs/development/ui/layout/box-constraints Pero estoy de acuerdo, no es fácil de encontrar. Tampoco hacen que la solución sea tan obvia como lo hizo Collin Jackson anteriormente.
Rap
El uso de este método se rompe mainAxisAlignmentpara el widget Fila. Con dos widgets de texto no hay problema, pero con un widget de texto y un widget Textfield contenido Flexiblese alinea a la izquierda sin espacios.
Hasen
¿Puedo pedirle que eche un vistazo a una pregunta relacionada con Flutter aquí: stackoverflow.com/questions/60565658/… ?
Istiaque Ahmed
30

Obtiene este error porque se TextFieldexpande en dirección horizontal y también lo hace el Row, por lo que debemos restringir el ancho del TextField, hay muchas formas de hacerlo.

  1. Utilizar Expanded

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

    Row(
      children: <Widget>[
        Flexible(child: TextField()),
        OtherWidget(),
      ],
    )
  3. Envuélvala Containero SizedBoxproporcionewidth

    Row(
      children: <Widget>[
        SizedBox(width: 100, child: TextField()),
        OtherWidget(),
      ],
    )       
PolicíasEn Carretera
fuente
2
Esta recomendación es muy útil. Cuando tienes múltiples TextFielden una fila.
Ben
11

debe usar Flexible para usar un campo de texto dentro de una fila.

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


              ],//widget
            ),//row
Ajit Paul
fuente
Creo que no necesitas el Container, puedes usarlo Flexibledirectamente.
Felipe Augusto
6

La solución es envolver Text()dentro de uno de los siguientes widgets: O Expandedo Flexible. Entonces, su código usando Expandido será como:

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

Como @Asif Shiraz mencionó, tuve el mismo problema y lo resolví envolviendo la columna en una flexible, aquí como esta,

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
fuente
0

Una solución simple es envolver su Text()interior a Container(). Entonces, su código será como:

Container(
      child: TextField()
)

Aquí también obtiene el atributo de ancho y alto de un contenedor para ajustar la apariencia de su campo de texto. No es necesario usarlo Flexiblesi está ajustando su campo de texto dentro de un Contenedor.

vs_lala
fuente
1
no resuelve la pregunta sin agregarwidth: n
user3249027