Flattern: Mindesthöhe in der horizontalen Listenansicht

75

Ich versuche, eine horizontale Bildlaufliste mit Elementen in Flutter zu erstellen, und ich möchte, dass diese Liste nur die erforderliche Höhe basierend auf ihren untergeordneten Elementen einnimmt. Mit Absicht " ListViewversucht zu erweitern, um den verfügbaren Raum in seiner Querrichtung anzupassen " (aus den Flutter-Dokumenten ), was ich auch dadurch bemerke, dass es die gesamte Höhe des Ansichtsfensters einnimmt, aber es gibt eine Möglichkeit, dies nicht zu tun Dies? Im Idealfall etwas Ähnliches (was offensichtlich nicht funktioniert):

new ListView(
  scrollDirection: Axis.horizontal,
  crossAxisSize: CrossAxisSize.min,
  children: <Widget>[
    new ListItem(),
    new ListItem(),
    // ...
  ],
);

Mir ist klar , dass ein Weg , dies zu tun ist durch die Umhüllung ListViewin einem Containermit einer festen Höhe. Ich kenne jedoch nicht unbedingt die Höhe der Gegenstände:

new Container(
  height: 97.0,
  child: new ListView(
    scrollDirection: Axis.horizontal,
    children: <Widget>[
      new ListItem(),
      new ListItem(),
      // ...
    ],
  ),
);

Ich konnte eine „Lösung“ zusammen hacken, indem ich a Rowin a SingleChildScrollViewin a Columnmit a verschachtelte mainAxisSize: MainAxisSize.min. Für mich ist dies jedoch keine Lösung:

new Column(
  mainAxisSize: MainAxisSize.min,
  children: <Widget>[
    new SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: new Row(
        children: <Widget>[
          new ListItem(),
          new ListItem(),
          // ...
        ],
      ),
    ),
  ],
);
sindrenm
quelle
9
Das gleiche Problem, haben Sie das jemals herausgefunden?
AntonB
2
Noch keine Lösung für dieses Problem, nein.
Sindrenm
1
Danke, shrinkWrap hat bei mir nicht funktioniert. Ihr Code funktioniert jedoch wie folgt: SingleChildScrollView (scrollDirection: Axis.horizontal, child: new Row (/ * Fügen Sie Ihre Widgets hier ein * /),) Wenn Sie jemals eine "bessere" Lösung gefunden haben, lassen Sie es uns wissen!
Nk54
1
@sindrenm Ich mag die Column / SingleChildScrollView / Row-Kombination und habe beschlossen, einfach ein StatelessWidget (das ich ScrollableRow nannte) daraus zu erstellen. Ich denke, es erledigt den Job und ich sehe kein wirkliches Problem damit. Ich sehe es nur als eine Möglichkeit, genau anzugeben, was Sie wollen, und indem ich daraus ein Widget erstelle, kann ich es sauber und präzise verwenden.
SamJakob
Also können wir am Ende nicht dafür sorgen, dass die Horizontale ListViewdie Höhe hat, die auf der Größe der Kinder basiert? Ist die SingleChildScrollViewBasis ListViewdie einzige Option? Ich würde wirklich gerne ein verwenden, ListViewda es semantisch korrekter ist.
Ionel Lupu

Antworten:

27

Setzen Sie einfach die shrinkEigenschaft von ListViewauf trueund es passt eher zum Raum als zur Erweiterung.

Beispiel:

ListView(
        shrinkWrap: true, //just set this property
        padding: const EdgeInsets.all(8.0),
        children: listItems.toList(),
      ),
Taha Ali
quelle
34
shrinkWrapwird die ListViewentlang der Hauptachse schrumpfen . Nicht wie gewünscht entlang der Querachse.
AnEnigmaticBug
von api.flutter.dev: Das Schrumpfen des Inhalts der Bildlaufansicht ist erheblich teurer als das Erweitern auf die maximal zulässige Größe ... siehe: api.flutter.dev/flutter/widgets/AnimatedList/shrinkWrap.html
Yehuda Kremer
15

Verwenden Sie ConstrainedBoxzum Einstellen minHeightundmaxHeight

ConstrainedBox(
  constraints: new BoxConstraints(
    minHeight: 35.0,
    maxHeight: 160.0,
  ),

  child: new ListView(
    shrinkWrap: true,
    children: <Widget>[
      new ListItem(),
      new ListItem(),
    ],

  ),
)
Davit Varamashvili
quelle
26
Wie würde ich dies tun, ohne die minimalen / maximalen Höhen der Listenelemente zu kennen?
Sindrenm
@sindrenm Müssen Sie wirklich die minimalen / maximalen Höhen kennen? Ich meine, Sie können die Höhe als Beispiel auf 1 bis 1000 einstellen, und alles, was zählt, ist, dass die Größe von ListView an die gewünschte Höhe angepasst wird. Lass es mich wissen, wenn mir etwas fehlt
Texv
3

Ich verwende einen horizontalen Listenansicht-Builder für Container, um zu verhindern, dass der Container die volle Höhe annimmt. Ich habe ihn gerade mit Center umwickelt und er hat perfekt funktioniert.

itemBuilder: (context, i){
              return Center(child: word_on_line(titles[i]));
          }
Fethi
quelle
1
Dies ist eine sehr gute Lösung. Vielen Dank. Ich frage mich, warum ich vorher nicht darüber
Alessio
1

Verwenden Sie Erweitert

 Expanded(
        child:ListView.separated(
          shrinkWrap: true,
        padding: EdgeInsets.all(10),
        separatorBuilder: (BuildContext context, int index) {
          return Align(
            alignment: Alignment.centerRight,
            child: Container(
              height: 0.5,
              width: MediaQuery.of(context).size.width / 1.3,
              child: Divider(),
            ),
          );
        },
        itemCount: dataMasterClass.length,
        itemBuilder: (BuildContext context, int index) {

          Datum datum = dataMasterClass[index];
         return sendItem(datum);

        },)
      )  ,
Rajesh Narwal
quelle
1

Wenn Sie alle oben genannten Lösungen anwenden, wird noch keine passende Antwort gefunden, die uns hilft, die horizontale Listenansicht festzulegen, wenn wir die Höhe nicht kennen. wir müssen in allen Fällen die Höhe einstellen. Daher habe ich die folgende Lösung angewendet, die für mich funktioniert, ohne eine Höhe für die Listenelemente anzugeben. was @sindrenm bereits in seiner Frage erwähnt hat. deshalb würde ich gerne so weitermachen, bis eine praktikable Lösung gefunden wird. Ich habe shrinkWrap: true angewendet, aber es wird die ListView entlang der Hauptachse verkleinern. (nur für vertikale Bildlaufansicht) und Nicht entlang der Querachse, wie in der Frage gestellt. In naher Zukunft kann jeder diese Lösung auch in der Produktion einsetzen. Sie eignet sich hervorragend für alle horizontalen Listen.

//below declared somewhere in a class above any method and assume list has filled from some API.
var mylist = List<myModel>();


SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          children: [
                for (int index = 0; index < mylist.length; index++) 
                      listItem(mylist[index]);
         ],
        ),
      ),
    ),

    listItem(){
      return Column(
         children[
            widget1(),
            widget2().... etc..
      ]);
    }
Dhiren
quelle
0

Das Einpacken des Widgets Columnmit mainAxisSize: MainAxisSize.minhat für mich funktioniert. Sie können versuchen, das heighthier zu ändern .

var data = [
      {'name': 'Shopping', 'icon': Icons.local_shipping},
      {'name': 'Service', 'icon': Icons.room_service},
      {'name': 'Hotel', 'icon': Icons.hotel},
      {'name': 'More', 'icon': Icons.more}
];

new Container(
        constraints: new BoxConstraints(
          minHeight: 40.0,
          maxHeight: 60.0,
        ),
        color: Colors.transparent,
        child: new ListView(
          scrollDirection: Axis.horizontal,
          children: data
              .map<Widget>((e) => Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      new Container(
                        width: 40,
                        height: 50, // try to change this.
                        color: Colors.transparent,
                        margin: EdgeInsets.only(right: 20, left: 4),
                        child: ClipOval(
                          child: Container(
                            padding: EdgeInsets.all(4),
                            color: Colors.white,
                            child: Icon(
                              e["icon"],
                              color: Colors.grey,
                              size: 30,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ))
              .toList(),
        ));
Sanjay Sharma
quelle