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),
          ),
        ),
      );
Charles Jr.
quelle

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"),
      )
    ],
  ),
)
Deutsche Saprykin
quelle
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,
    )
  ],
);
up2up
quelle
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
        )
      ],
    )
CopsOnRoad
quelle
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,
Entwickeln
quelle
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.

jitsm555
quelle
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),
    )
  ],
));

}}

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

     ],
   ), 
  );
UN..D
quelle
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) {
            ...
        },
        ),
    ),
],

);

Moein Fazeli
quelle
-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),
            ],
          ),
        ),
      ],
    ),
  ),
)
Morteza Rastgoo
quelle