Làm thế nào để thêm một ListView vào một cột trong Flutter?


124

Tôi đang cố gắng tạo một trang đăng nhập đơn giản cho ứng dụng Flutter của mình. Tôi đã tạo thành công các Trường Văn bản và các nút Đăng nhập / Đăng nhập. Tôi muốn thêm một ListView ngang. Khi tôi chạy mã, các phần tử của tôi biến mất, nếu tôi làm điều đó mà không có ListView, thì nó vẫn ổn. Làm thế nào tôi có thể làm điều này một cách chính xác?

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

Câu trả lời:


73

Bạn có thể kiểm tra đầu ra của bảng điều khiển. Nó in lỗi:

Xác nhận sau đây đã được đưa ra trong quá trình performanceResize (): Khung nhìn ngang được cung cấp chiều cao không giới hạn. Các khung nhìn mở rộng theo trục chéo để lấp đầy vùng chứa của chúng và hạn chế con của chúng phù hợp với phạm vi của chúng trong trục chéo. Trong trường hợp này, một khung nhìn ngang được cung cấp một lượng không gian dọc không giới hạn để mở rộng.

Bạn cần thêm giới hạn chiều cao vào danh sách ngang của mình. Ví dụ: bọc trong Container với chiều cao:

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
hai câu trả lời tiếp theo đưa ra hai giải pháp khác và giải thích những gì đang xảy ra.
pashute

299

Tôi cũng có vấn đề này. Giải pháp của tôi là sử dụng Expandedwidget để mở rộng không gian còn lại.

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

2
Đây là một giải pháp tuyệt vời vì nó cho phép chiều cao / chiều rộng có kích thước thay đổi của ListView, giống như khi bạn muốn nó chỉ chiếm không gian còn lại. Nó cho phép bạn tính đến các kích thước màn hình khác nhau khi quá khó để biết chính xác chiều cao / chiều rộng.
Daniel Allen,

1
Đây phải là câu trả lời được chấp nhận. Giải pháp này cho phép ListView sử dụng phần còn lại của màn hình mà không cần phải xử lý truy vấn phương tiện.
Terence Ponce,

Tôi còn quá mới đối với Flutter để biết tại sao nó hoạt động, nhưng tôi rất vui vì nó đã làm được. Cảm ơn bạn. Thông báo lỗi của Flutter không hữu ích lắm để giải thích nguyên nhân gốc rễ của vấn đề này cho một người không phải là chuyên gia.
devdanke

Cảm ơn, câu trả lời của bạn tiết kiệm thời gian của tôi.
Licat Julius

125

Lý do cho lỗi:

Columnmở rộng đến kích thước tối đa theo hướng trục chính (trục tung) và như vậy ListView.

Các giải pháp

Vì vậy, bạn cần hạn chế chiều cao của ListView. Có nhiều cách để thực hiện, bạn có thể lựa chọn phù hợp nhất với nhu cầu của mình.


  1. Nếu bạn muốn cho phép ListViewđể mất tất cả còn lại bên trong không gian Columnsử dụng Expanded.

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

  1. Nếu bạn muốn giới hạn của bạn ListViewđến một số nhất định height, bạn có thể sử dụng SizedBox.

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

  1. Nếu của bạn ListViewlà nhỏ, bạn có thể thử shrinkWraptài sản trên đó.

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

Chiều cao của tôi không nên cố định và các câu trả lời khác không làm việc cho tôi = /
Daniel Vilela

1
@DanielVilela Tùy chọn 1 sẽ phù hợp với bạn. Nếu không, vui lòng đăng nó dưới dạng câu hỏi và nếu tôi sẵn sàng, tôi có thể trả lời nó.
CopsOnRoad,

1
Tôi đã nhận nó để làm việc! Cảm ơn. Tôi đã phải đặt một Expanded () ở một số nơi chiến lược.
Daniel Vilela

Cảm ơn, tôi không nghĩ về Mở rộng.
Gilvan André

Cám ơn shrinkwrap: true trong ListView ()
Rana Hyder

18

Tôi có SingleChildScrollViewvới tư cách là cha mẹ, và một ColumnWidget và sau đó là List View Widget là đứa con cuối cùng.

Thêm các thuộc tính này trong Dạng xem Danh sách Đã làm việc cho tôi.

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

14

Widget được mở rộng sẽ tăng kích thước của nó nhiều nhất có thể với không gian có sẵn Vì ListView về cơ bản có chiều cao vô hạn nên sẽ gây ra lỗi.

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

Ở đây chúng ta nên sử dụng widget Linh hoạt vì nó sẽ chỉ chiếm dung lượng cần thiết khi Mở rộng chiếm toàn màn hình ngay cả khi không có đủ tiện ích để hiển thị trên toàn màn hình.


10

Trên thực tế, khi bạn đọc tài liệu, ListView phải ở bên trong Widget được mở rộng để nó có thể hoạt động.

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

}


7

Như đã được đề cập bởi những người khác ở trên, Wrap listview với Expanded là giải pháp.

Nhưng khi bạn xử lý các Cột lồng nhau, bạn cũng sẽ cần giới hạn ListView của mình ở một độ cao nhất định (đã gặp phải vấn đề này rất nhiều).

Nếu bất cứ ai có giải pháp khác, xin vui lòng đề cập trong bình luận hoặc thêm câu trả lời.

Thí dụ

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

     ],
   ), 
  );

trong các cột lồng nhau không sử dụng được mở rộng chỉ sử dụng thuộc tính shkWrap: true, vật lý: NeverScrolPhysics () trong listView
Mohamed Kamel

5

Bạn có thể sử dụng FlexFlexiblecác vật dụng. ví dụ:

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

);


-1

Hãy thử sử dụng 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),
            ],
          ),
        ),
      ],
    ),
  ),
)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.