Flutter'da bir Sütuna ListView nasıl eklenir?


125

Flutter uygulamam için basit bir giriş sayfası oluşturmaya çalışıyorum. TextFields ve Login / Signin düğmelerini başarıyla oluşturdum. Yatay bir ListView eklemek istiyorum. Kodu çalıştırdığımda öğelerim kaybolur, eğer bunu ListView olmadan yaparsam, yine sorun olmaz. Bunu nasıl doğru bir şekilde yapabilirim?

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

Yanıtlar:


75

Konsol çıktısını kontrol edebilirsiniz. Şu hatayı yazdırıyor:

PerformResize () sırasında aşağıdaki iddia atıldı: Yatay görünüm alanına sınırsız yükseklik verildi. Görüntü alanları, kapsayıcılarını doldurmak ve çocuklarını çapraz eksendeki kapsamlarına uyacak şekilde sınırlamak için çapraz eksende genişler. Bu durumda, yatay bir görüntü alanına genişlemesi için sınırsız miktarda dikey alan verildi.

Yatay listenize yükseklik sınırlaması eklemeniz gerekir. Örneğin, Konteyner içerisine şu yükseklikte sarın:

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
sonraki iki cevap iki çözüm daha verir ve neler olduğunu açıklar.
2019

299

Bende de bu sorun var. Benim çözümüm Expandedkalan alanı genişletmek için widget kullanmak .

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

2
Bu harika bir çözümdür, çünkü ListView'ın, sadece kalan alanı kaplamasını istediğinizde olduğu gibi değişken boyutlu yüksekliklere / genişliklere izin verir. Tam yüksekliği / genişliği bilmek çok zor olduğunda değişen ekran boyutlarını hesaba katmanıza olanak tanır.
Daniel Allen

1
Kabul edilen cevap bu olmalıdır. Bu çözüm, ListView'ün medya sorgusuyla uğraşmak zorunda kalmadan ekranın geri kalanını almasını sağlar.
Terence Ponce

Bunun neden işe yaradığını bilemeyecek kadar Flutter'da yeniyim, ama işe yaradığına sevindim. Teşekkür ederim. Uzman olmayan biri için Flutter'ın hata mesajları bu sorunun temel nedenini açıklamaya pek yardımcı olmadı.
devdanke

Teşekkürler, cevabınız zaman kazandırıyor.
Licat Julius

126

Hatanın nedeni:

Columnana eksen yönünde (dikey eksen) maksimum boyuta genişler ve ListView.

Çözümler

Bu nedenle ListView,. Bunu yapmanın birçok yolu vardır, ihtiyacınıza en uygun olanı seçebilirsiniz.


  1. Kullanım ListViewiçinde kalan tüm alanı kaplamaya izin vermek istiyorsanız .ColumnExpanded

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

  1. Sınırınıza istiyorsanız ListViewbelli etmek height, kullanabilirsiniz SizedBox.

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

  1. Eğer senin ListViewküçük, sen deneyebilirsiniz shrinkWrapüzerinde mülkiyet.

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

Boyum sabitlenmemeli ve diğer cevaplar benim için işe yaramadı = /
Daniel Vilela

1
@DanielVilela Seçenek 1 sizin için çalışmalı. Değilse lütfen soru olarak gönderin ve müsait olursam cevaplayabilirim.
CopsOnRoad

1
Çalışmasını sağladım! Teşekkürler. Bazı stratejik yerlere Expanded () koymak zorunda kaldım.
Daniel Vilela

Teşekkürler, Expanded'ı düşünmedim.
Gilvan André

ShrinkWrap için teşekkürler: ListView () doğru
Rana Hyder

18

Ben SingleChildScrollViewbir ebeveyn olarak ve bir ColumnWidget ve sonra Liste Görünümü Widget son çocuğu olarak.

Bu özellikleri Liste Görünümü'ne eklemek benim için çalıştı.

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

15

Genişletilmiş Widget, mevcut alanla olabildiğince boyutunu artırır ListView esasen sonsuz bir yüksekliğe sahip olduğundan, bir hataya neden olur.

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

Burada Esnek parçacığı kullanmalıyız çünkü Genişletme tam ekranda görüntülenmek için yeterli pencere öğesi olmasa bile tam ekran alacağı için gereken alanı kaplar.


10

Aslında, belgeleri okuduğunuzda ListView, çalışabilmesi için Genişletilmiş Pencere Öğesinin içinde olmalıdır.

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

}


7

Yukarıda başkaları tarafından da belirtildiği gibi, çözüm, Expanded ile Wrap listview'dir.

Ancak iç içe geçmiş Sütunlar ile uğraşırken, ListView'unuzu belirli bir yükseklikle sınırlamanız da gerekecektir (bu sorunla çok karşılaştık).

Herhangi birinin başka bir çözümü varsa, lütfen yorumda belirtin veya yanıt ekleyin.

Misal

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

     ],
   ), 
  );

iç içe sütunlarda genişletilmiş kullanmayın sadece listView'daki shrikWrap: true, physics: NeverScrolPhysics () özelliklerini kullanın
Mohamed Kamel

5

FlexVe Flexiblewidget'ları kullanabilirsiniz . Örneğin:

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

Şerit kullanmayı deneyin:

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),
            ],
          ),
        ),
      ],
    ),
  ),
)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.