Wie füge ich eine ListView zu einer Spalte in Flutter hinzu?


121

Ich versuche, eine einfache Anmeldeseite für meine Flutter-App zu erstellen. Ich habe die Schaltflächen TextFields und Login / Signin erfolgreich erstellt. Ich möchte eine horizontale ListView hinzufügen. Wenn ich den Code ausführe, verschwinden meine Elemente. Wenn ich es ohne ListView mache, ist es wieder in Ordnung. Wie kann ich das richtig machen?

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

Antworten:


72

Sie können die Konsolenausgabe überprüfen. Es wird ein Fehler ausgegeben:

Die folgende Behauptung wurde während performResize () ausgelöst: Das horizontale Ansichtsfenster erhielt eine unbegrenzte Höhe. Ansichtsfenster werden in der Querachse erweitert, um ihren Container zu füllen und ihre untergeordneten Elemente so einzuschränken, dass sie ihrer Ausdehnung in der Querachse entsprechen. In diesem Fall wurde einem horizontalen Ansichtsfenster ein unbegrenzter vertikaler Raum zum Erweitern zugewiesen.

Sie müssen Ihrer horizontalen Liste eine Höhenbeschränkung hinzufügen. ZB in Behälter mit Höhe einwickeln:

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
Die nächsten beiden Antworten geben zwei weitere Lösungen und erklären, was passiert.
Pashute

296

Ich habe auch dieses Problem. Meine Lösung ist ExpandedWidget verwenden, um den verbleibenden Speicherplatz zu erweitern.

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

2
Dies ist eine großartige Lösung, da sie Höhen / Breiten variabler Größe der ListView zulässt, beispielsweise wenn Sie möchten, dass sie nur den verbleibenden Platz einnimmt. Sie können unterschiedliche Bildschirmgrößen berücksichtigen, wenn es zu schwierig ist, die genaue Höhe / Breite zu ermitteln.
Daniel Allen

1
Dies sollte die akzeptierte Antwort sein. Mit dieser Lösung kann ListView den Rest des Bildschirms einnehmen, ohne sich mit Medienabfragen befassen zu müssen.
Terence Ponce

Ich bin zu neu in Flutter, um zu wissen, warum das funktioniert, aber ich bin froh, dass es funktioniert. Danke dir. Die Fehlermeldungen von Flutter waren nicht sehr hilfreich, um die Ursache dieses Problems für einen Nicht-Experten zu erklären.
Devdanke

Danke, deine Antwort spart mir Zeit.
Licat Julius

124

Grund für den Fehler:

Column erweitert sich auf die maximale Größe in Richtung der Hauptachse (vertikale Achse), ebenso wie die ListView .

Lösungen

Sie müssen also die Höhe des ListView. Es gibt viele Möglichkeiten, dies zu tun. Sie können wählen, welche Ihren Anforderungen am besten entspricht.


  1. Wenn Sie zulassen möchten, dass ListViewder gesamte verbleibende Platz im Inneren belegt Columnwird Expanded.

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

  1. Wenn Sie Ihre ListViewauf bestimmte beschränken möchten height, können Sie verwenden SizedBox.

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

  1. Wenn Sie ListViewklein sind, können Sie versuchen, shrinkWrapEigentum darauf.

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

Meine Größe sollte nicht festgelegt werden und die anderen Antworten funktionierten nicht für mich = /
Daniel Vilela

1
@ DanielVilela Option 1 sollte für Sie funktionieren. Wenn nicht, poste es bitte als Frage und wenn ich verfügbar bin, kann ich es beantworten.
CopsOnRoad

1
Ich habe es zum Laufen gebracht! Vielen Dank. Ich musste an einigen strategischen Stellen ein Expanded () einfügen.
Daniel Vilela

Danke, ich habe nicht an Expanded gedacht.
Gilvan André

Danke für shrinkWrap: true in ListView ()
Rana Hyder

18

Ich habe SingleChildScrollViewals Eltern und eineColumn Widget und dann List View Widget als letztes Kind.

Hinzufügen dieser Eigenschaften in der Listenansicht Hat bei mir funktioniert.

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

13

Das erweiterte Widget vergrößert es so weit wie möglich mit dem verfügbaren Speicherplatz. Da ListView im Wesentlichen eine unendliche Höhe hat, verursacht es einen Fehler.

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

Hier sollten wir das flexible Widget verwenden, da es nur den Platz beansprucht, den es als erweitertes Vollbild benötigt, auch wenn nicht genügend Widgets zum Rendern im Vollbildmodus vorhanden sind.


10

Wenn Sie Dokumente lesen, sollte sich ListView im erweiterten Widget befinden, damit es funktioniert.

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

}}


7

Wie bereits von anderen erwähnt, ist Wrap listview with Expanded die Lösung.

Wenn Sie sich jedoch mit verschachtelten Spalten befassen, müssen Sie Ihre ListView auch auf eine bestimmte Höhe beschränken (dieses Problem trat häufig auf).

Wenn jemand eine andere Lösung hat, bitte im Kommentar erwähnen oder Antwort hinzufügen.

Beispiel

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

     ],
   ), 
  );

Verwenden Sie in verschachtelten Spalten nicht expandiert. Verwenden Sie einfach die Eigenschaften shrikWrap: true, physics: NeverScrolPhysics () in listView
Mohamed Kamel

3

Sie können Flexund FlexibleWidgets verwenden. beispielsweise:

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

);


-1

Versuchen Sie es mit Splittern:

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),
            ],
          ),
        ),
      ],
    ),
  ),
)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.