¿Cómo agregar un ListView a una columna en Flutter?


125

Estoy tratando de construir una página de inicio de sesión simple para mi aplicación Flutter. He creado con éxito los botones TextFields y Login / Signin. Quiero agregar un ListView horizontal. Cuando ejecuto el código, mis elementos desaparecen, si lo hago sin ListView, está bien de nuevo. ¿Cómo puedo hacer esto correctamente?

return new MaterialApp(
        home: new Scaffold(
          appBar: new AppBar(
            title: new Text("Login / Signup"),
          ),
          body: new Container(
            child: new Center(
              child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new TextField(
                    decoration: new InputDecoration(
                      hintText: "E M A I L    A D D R E S S"
                    ),
                  ),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new TextField(obscureText: true,
                    decoration: new InputDecoration(
                      hintText: "P A S S W O R D"
                    ),
                    ),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new TextField(decoration: new InputDecoration(
                    hintText: "U S E R N A M E"
                  ),),
                  new RaisedButton(onPressed: null,
                  child:  new Text("SIGNUP"),),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new RaisedButton(onPressed: null,
                  child: new Text("LOGIN"),),
                  new Padding(padding: new EdgeInsets.all(15.00)),
                  new ListView(scrollDirection: Axis.horizontal,
                  children: <Widget>[
                    new RaisedButton(onPressed: null,
                    child: new Text("Facebook"),),
                    new Padding(padding: new EdgeInsets.all(5.00)),
                    new RaisedButton(onPressed: null,
                    child: new Text("Google"),)
                  ],)

                ],
              ),
            ),
            margin: new EdgeInsets.all(15.00),
          ),
        ),
      );

Respuestas:


74

Puede comprobar la salida de la consola. Imprime error:

Se lanzó la siguiente aserción durante performResize (): Se le dio una altura ilimitada a la ventana de visualización horizontal. Las ventanas gráficas se expanden en el eje transversal para llenar su contenedor y restringir a sus hijos para que coincidan con su extensión en el eje transversal. En este caso, a una ventana de visualización horizontal se le dio una cantidad ilimitada de espacio vertical para expandirse.

Necesita agregar restricción de altura a su lista horizontal. Por ejemplo, envolver en contenedor con altura:

Container(
  height: 44.0,
  child: ListView(
    scrollDirection: Axis.horizontal,
    children: <Widget>[
      RaisedButton(
        onPressed: null,
        child: Text("Facebook"),
      ),
      Padding(padding: EdgeInsets.all(5.00)),
      RaisedButton(
        onPressed: null,
        child: Text("Google"),
      )
    ],
  ),
)

6
las siguientes dos respuestas dan otras dos soluciones y explican lo que está sucediendo.
pashute

299

Yo también tengo este problema. Mi solución es usar el Expandedwidget para expandir el espacio restante.

new Column(
  children: <Widget>[
    new Expanded(
      child: horizontalList,
    )
  ],
);

2
Esta es una gran solución porque permite alturas / anchos de tamaño variable de ListView, como cuando desea que solo ocupe el espacio restante. Le permite tener en cuenta los diferentes tamaños de pantalla cuando es demasiado difícil saber la altura / ancho exactos.
Daniel Allen

1
Esta debería ser la respuesta aceptada. Esta solución permite que ListView tome el resto de la pantalla sin tener que lidiar con consultas de medios.
Terence Ponce

Soy demasiado nuevo en Flutter para saber por qué funciona, pero me alegro de que así sea. Gracias. Los mensajes de error de Flutter no fueron muy útiles para explicar la causa raíz de este problema para un no experto.
devdanke

Gracias, tu respuesta me ahorra tiempo.
Licat Julius

125

Razón del error:

Column se expande al tamaño máximo en la dirección del eje principal (eje vertical), y también lo hace ListView .

Soluciones

Por lo tanto, debe restringir la altura del ListView. Hay muchas formas de hacerlo, puedes elegir la que mejor se adapte a tus necesidades.


  1. Si desea permitir ListViewque ocupe todo el espacio interior restante, Columnutilice Expanded.

    Column(
      children: <Widget>[
        Expanded(
          child: ListView(...),
        )
      ],
    )

  1. Si desea limitar su ListViewa cierto height, puede utilizar SizedBox.

    Column(
      children: <Widget>[
        SizedBox(
          height: 200, // constrain height
          child: ListView(),
        )
      ],
    )

  1. Si ListViewes pequeño, puede probar shrinkWrappropiedades en él.

    Column(
      children: <Widget>[
        ListView(
          shrinkWrap: true, // use it
        )
      ],
    )

Mi altura no debería ser fija y las otras respuestas no me funcionaron = /
Daniel Vilela

1
@DanielVilela La opción 1 debería funcionar para usted. De lo contrario, publíquelo como pregunta y, si estoy disponible, puedo responderlo.
CopsOnRoad

1
¡Yo tengo que trabajar! Gracias. Tuve que poner un Expanded () en algunos lugares estratégicos.
Daniel Vilela

Gracias, no pensé en Expanded.
Gilvan André

Gracias por shrinkWrap: verdadero en ListView ()
Rana Hyder

18

Tengo SingleChildScrollViewcomo padre, un Columnwidget y luego un widget de vista de lista como último hijo.

Agregar estas propiedades en la vista de lista funcionó para mí.

  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  scrollDirection: Axis.vertical,

14

El widget expandido aumenta su tamaño tanto como puede con el espacio disponible. Dado que ListView esencialmente tiene una altura infinita, provocará un error.

 Column(
  children: <Widget>[
    Flexible(
      child: ListView(...),
    )
  ],
)

Aquí deberíamos usar el widget flexible, ya que solo ocupará el espacio que requirió como expandido, tomar pantalla completa, incluso si no hay suficientes widgets para renderizar en pantalla completa.


10

En realidad, cuando lee documentos, ListView debe estar dentro del widget expandido para que pueda funcionar.

  Widget build(BuildContext context) {
return Scaffold(
    body: Column(
  children: <Widget>[
    Align(
      child: PayableWidget(),
    ),
    Expanded(
      child: _myListView(context),
    )
  ],
));

}


7

Como otros han mencionado anteriormente, Wrap listview with Expanded es la solución.

Pero cuando trabaje con columnas anidadas, también deberá limitar su ListView a una cierta altura (enfrentó mucho este problema).

Si alguien tiene otra solución, mencione en el comentario o agregue una respuesta.

Ejemplo

  SingleChildScrollView(
   child: Column(
     children: <Widget>[
       Image(image: ),//<< any widgets added
       SizedBox(),
       Column(
         children: <Widget>[
           Text('header'),  //<< any widgets added
            Expanded(child: 
            ListView.builder(
              //here your code
               scrollDirection: Axis.horizontal,
        itemCount: items.length,
        itemBuilder: (BuildContext context, int index) {
            return Container();
                   } 
         )
        ),
        Divider(),//<< any widgets added
         ],
       ),

     ],
   ), 
  );

en columnas anidadas no use expandido solo use shrikWrap: true, propiedades físicas: NeverScrolPhysics () en listView
Mohamed Kamel

5

Puede utilizar Flexy Flexiblewidgets. por ejemplo:

Flex(
direction: Axis.vertical,
children: <Widget>[
    ... other widgets ...
    Flexible(
        flex: 1,
        child: ListView.builder(
        itemCount: ...,
        itemBuilder: (context, index) {
            ...
        },
        ),
    ),
],

);


0
return new MaterialApp(
    home: new Scaffold(
      appBar: new AppBar(
        title: new Text("Login / Signup"),
      ),
      body: new Container(
        child: new Center(
          child: ListView(
          //mainAxisAlignment: MainAxisAlignment.center,
          scrollDirection: Axis.vertical,
            children: <Widget>[
              new TextField(
                decoration: new InputDecoration(
                  hintText: "E M A I L    A D D R E S S"
                ),
              ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(obscureText: true,
                decoration: new InputDecoration(
                  hintText: "P A S S W O R D"
                ),
                ),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new TextField(decoration: new InputDecoration(
                hintText: "U S E R N A M E"
              ),),
              new RaisedButton(onPressed: null,
              child:  new Text("SIGNUP"),),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new RaisedButton(onPressed: null,
              child: new Text("LOGIN"),),
              new Padding(padding: new EdgeInsets.all(15.00)),
              new ListView(scrollDirection: Axis.horizontal,
              children: <Widget>[
                new RaisedButton(onPressed: null,
                child: new Text("Facebook"),),
                new Padding(padding: new EdgeInsets.all(5.00)),
                new RaisedButton(onPressed: null,
                child: new Text("Google"),)
              ],)

            ],
          ),
        ),
        margin: new EdgeInsets.all(15.00),
      ),
    ),
  );

-1

Intente usar Slivers:

Container(
    child: CustomScrollView(
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Header 1"),
              HeaderWidget("Header 2"),
              HeaderWidget("Header 3"),
              HeaderWidget("Header 4"),
            ],
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
              BodyWidget(Colors.green),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget(Colors.blue),
              BodyWidget(Colors.green),
              BodyWidget(Colors.yellow),
              BodyWidget(Colors.orange),
              BodyWidget(Colors.blue),
              BodyWidget(Colors.red),
            ],
          ),
        ),
      ],
    ),
  ),
)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.