Come aggiungere un ListView a una colonna in Flutter?


125

Sto cercando di creare una semplice pagina di accesso per la mia app Flutter. Ho creato con successo i pulsanti TextFields e Login / Signin. Voglio aggiungere un ListView orizzontale. Quando eseguo il codice i miei elementi scompaiono, se lo faccio senza ListView, va di nuovo bene. Come posso farlo correttamente?

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),
          ),
        ),
      );

Risposte:


75

Puoi controllare l'output della console. Stampa errore:

La seguente asserzione è stata generata durante performResize (): alla visualizzazione orizzontale è stata assegnata un'altezza illimitata. Le finestre si espandono nell'asse trasversale per riempire il loro contenitore e vincolare i loro figli in modo che corrispondano alla loro estensione nell'asse trasversale. In questo caso, a una finestra orizzontale è stata assegnata una quantità illimitata di spazio verticale in cui espandersi.

È necessario aggiungere un vincolo di altezza all'elenco orizzontale. Ad esempio avvolgere in un contenitore con altezza:

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
le successive due risposte danno altre due soluzioni e spiegano cosa sta succedendo.
pashute

299

Anch'io ho questo problema. La mia soluzione è utilizzare il Expandedwidget per espandere lo spazio rimanente.

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

2
Questa è un'ottima soluzione perché consente altezze / larghezze di dimensioni variabili di ListView, come quando si desidera che occupi solo lo spazio rimanente. Ti consente di tenere conto delle diverse dimensioni dello schermo quando è troppo difficile conoscere l'esatta altezza / larghezza.
Daniel Allen

1
Questa dovrebbe essere la risposta accettata. Questa soluzione consente a ListView di occupare il resto dello schermo senza doversi occupare di media query.
Terence Ponce

Sono troppo nuovo per Flutter per sapere perché funziona, ma sono contento che funzioni. Grazie. I messaggi di errore di Flutter non sono stati molto utili per spiegare la causa principale di questo problema per un non esperto.
devdanke

Grazie, la tua risposta mi fa risparmiare tempo.
Licat Julius il

126

Motivo dell'errore:

Columnsi espande alla dimensione massima nella direzione dell'asse principale (asse verticale), così come il file ListView.

soluzioni

Quindi, è necessario limitare l'altezza del file ListView. Ci sono molti modi per farlo, puoi scegliere quello più adatto alle tue esigenze.


  1. Se si desidera consentire ListViewdi occupare tutto lo spazio rimanente, Columnutilizzarlo Expanded.

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

  1. Se vuoi limitare il tuo ListViewa determinati height, puoi usare SizedBox.

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

  1. Se il tuo ListViewè piccolo, puoi provare la shrinkWrapproprietà su di esso.

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

La mia altezza non dovrebbe essere corretta e le altre risposte non hanno funzionato per me = /
Daniel Vilela

1
@DanielVilela Opzione 1 dovrebbe funzionare per te. In caso contrario, per favore pubblicalo come domanda e se sono disponibile posso rispondere.
CopsOnRoad

1
Devo farlo funzionare! Grazie. Ho dovuto mettere un Expanded () in alcuni punti strategici.
Daniel Vilela,

Grazie, non ho pensato a Expanded.
Gilvan André

Grazie per shrinkWrap: true in ListView ()
Rana Hyder

18

Ho SingleChildScrollViewcome genitore e unoColumn widget e poi widget Visualizzazione elenco come ultimo figlio.

L'aggiunta di queste proprietà nella visualizzazione elenco ha funzionato per me.

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

14

Widget espanso aumenta le sue dimensioni il più possibile con lo spazio disponibile Poiché ListView ha essenzialmente un'altezza infinita, causerà un errore.

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

Qui dovremmo usare il widget flessibile in quanto occuperà solo lo spazio necessario poiché l'espansione occupa lo schermo intero anche se non ci sono abbastanza widget per il rendering a schermo intero.


10

In realtà, quando leggi i documenti, ListView dovrebbe essere all'interno di Expanded Widget in modo che possa funzionare.

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

}


7

Come è stato accennato da altri sopra, la soluzione è Wrap listview con Expanded.

Ma quando ti occupi di colonne nidificate, dovrai anche limitare il tuo ListView a una certa altezza (affrontato molto questo problema).

Se qualcuno ha un'altra soluzione, per favore, menziona nel commento o aggiungi una risposta.

Esempio

  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
         ],
       ),

     ],
   ), 
  );

nelle colonne nidificate non usare espanso usa solo shrikWrap: true, physics: NeverScrolPhysics () proprietà in listView
Mohamed Kamel

5

Puoi usare Flexe Flexiblewidget. per esempio:

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

Prova a usare Tramutanti:

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),
            ],
          ),
        ),
      ],
    ),
  ),
)
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.