Bagaimana cara menambahkan ListView ke Kolom di Flutter?

125

Saya mencoba membuat halaman login sederhana untuk aplikasi Flutter saya. Saya telah berhasil membuat tombol TextFields dan Login / Signin. Saya ingin menambahkan ListView horizontal. Ketika saya menjalankan kode, elemen saya hilang, jika saya melakukannya tanpa ListView, tidak masalah lagi. Bagaimana saya bisa melakukan ini dengan benar?

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.
sumber

Jawaban:

75

Anda dapat memeriksa keluaran konsol. Ini mencetak kesalahan:

Penegasan berikut diberikan selama performResize (): Area pandang horizontal diberi ketinggian tak terbatas. Area pandang diperluas di sumbu silang untuk mengisi penampungnya dan membatasi turunannya agar sesuai dengan luasnya di sumbu silang. Dalam hal ini, area pandang horizontal diberi ruang vertikal dalam jumlah yang tidak terbatas untuk diperluas.

Anda perlu menambahkan batasan ketinggian ke daftar horizontal Anda. Misal bungkus dalam Container dengan tinggi:

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"),
      )
    ],
  ),
)
Saprykin Jerman
sumber
6
dua jawaban berikutnya memberikan dua solusi lain dan menjelaskan apa yang terjadi.
pashute
299

Saya punya masalah ini juga. Solusi saya adalah menggunakan Expandedwidget untuk memperluas ruang sisa.

new Column(
  children: <Widget>[
    new Expanded(
      child: horizontalList,
    )
  ],
);
up2up
sumber
2
Ini adalah solusi yang bagus karena memungkinkan untuk tinggi / lebar berukuran variabel dari ListView, seperti saat Anda ingin menggunakan ruang yang tersisa. Ini memungkinkan Anda memperhitungkan berbagai ukuran layar saat terlalu sulit untuk mengetahui tinggi / lebar yang tepat.
Daniel Allen
1
Ini harus menjadi jawaban yang diterima. Solusi ini memungkinkan ListView untuk mengambil seluruh layar tanpa harus berurusan dengan kueri media.
Terence Ponce
Saya terlalu baru mengenal Flutter untuk mengetahui mengapa ini berhasil, tetapi saya senang berhasil. Terima kasih. Pesan kesalahan Flutter tidak terlalu membantu untuk menjelaskan akar penyebab masalah ini bagi yang bukan ahli.
devdanke
Terima kasih, jawaban Anda menghemat waktu saya.
Licat Julius
126

Alasan terjadinya kesalahan:

Columnmeluas ke ukuran maksimum dalam arah sumbu utama (sumbu vertikal), dan begitu juga dengan ListView.

Solusi

Jadi, Anda perlu membatasi ketinggian ListView. Ada banyak cara untuk melakukannya, Anda bisa memilih yang paling sesuai dengan kebutuhan Anda.


  1. Jika Anda ingin mengizinkan ListViewuntuk mengambil semua ruang yang tersisa di dalam Columndigunakan Expanded.

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

  1. Jika Anda ingin membatasi Anda ListViewuntuk tertentu height, Anda dapat menggunakan SizedBox.

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

  1. Jika Anda ListViewkecil, Anda dapat mencoba shrinkWrapproperti di atasnya.

    Column(
      children: <Widget>[
        ListView(
          shrinkWrap: true, // use it
        )
      ],
    )
CopsOnRoad
sumber
Tinggi badan saya tidak boleh diperbaiki dan jawaban lain tidak berhasil untuk saya = /
Daniel Vilela
1
@DanielVilela Opsi 1 harus bekerja untuk Anda. Jika tidak silahkan posting sebagai pertanyaan dan jika saya tersedia saya bisa menjawabnya.
CopsOnRoad
1
Saya mendapatkannya untuk bekerja! Terima kasih. Saya harus meletakkan Expanded () di beberapa tempat strategis.
Daniel Vilela
Terima kasih, saya tidak berpikir tentang Diperluas.
Gilvan André
Terima kasih untuk shrinkWrap: benar di ListView ()
Rana Hyder
18

Saya memiliki SingleChildScrollViewsebagai orang tua, dan satu ColumnWidget dan kemudian Widget Tampilan Daftar sebagai anak terakhir.

Menambahkan properti ini di Tampilan Daftar Berhasil untuk saya.

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

Widget yang Diperluas meningkatkan ukurannya sebanyak mungkin dengan ruang yang tersedia Karena ListView pada dasarnya memiliki ketinggian yang tak terbatas, ini akan menyebabkan kesalahan.

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

Di sini kita harus menggunakan widget Fleksibel karena hanya akan mengambil ruang yang diperlukan karena Diperluas mengambil layar penuh meskipun tidak ada cukup widget untuk ditampilkan di layar penuh.

jitsm555
sumber
10

Sebenarnya, ketika Anda membaca dokumen, ListView harus berada di dalam Widget yang Diperluas agar dapat berfungsi.

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

}

Richie
sumber
7

Seperti yang telah disebutkan oleh orang lain di atas, Bungkus listview dengan Expanded adalah solusinya.

Tetapi ketika Anda berurusan dengan Kolom bersarang, Anda juga perlu membatasi ListView Anda ke ketinggian tertentu (sering menghadapi masalah ini).

Jika ada yang punya solusi lain, sebutkan di komentar atau tambahkan jawaban.

Contoh

  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
sumber
di kolom bersarang jangan gunakan diperluas cukup gunakan shrikWrap: true, physics: properti NeverScrolPhysics () di listView
Mohamed Kamel
5

Anda dapat menggunakan Flexdan Flexiblewidget. sebagai contoh:

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

);

Moein Fazeli
sumber
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),
      ),
    ),
  );
VenkatSainathReddy
sumber
-1

Coba gunakan Slivers:

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
sumber