Làm cách nào để đặt Chiều cao tùy chỉnh cho Widget trong GridView trong Flutter?


81

Ngay cả sau khi chỉ định chiều cao cho Container GridView, mã của tôi vẫn tạo ra các widget hình vuông.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> widgetList = ['A', 'B', 'C'];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(
        child: new GridView.count(
          crossAxisCount: 2,
          controller: new ScrollController(keepScrollOffset: false),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          children: widgetList.map((String value) {
            return new Container(
              height: 250.0,
              color: Colors.green,
              margin: new EdgeInsets.all(1.0),
              child: new Center(
                child: new Text(
                  value,
                  style: new TextStyle(fontSize: 50.0,color: Colors.white),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

Đầu ra của đoạn mã trên như được hiển thị bên trái. Làm cách nào để tôi có được GridView với tiện ích chiều cao tùy chỉnh như được hiển thị bên phải?

đầu ra Đầu ra yêu cầu


Câu trả lời:


147

Điều quan trọng là childAspectRatio. Giá trị này được sử dụng để xác định bố cục trong GridView. Để có được khía cạnh mong muốn, bạn phải đặt nó thành ( itemWidth/ itemHeight). Giải pháp sẽ là:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> widgetList = ['A', 'B', 'C'];

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;

    /*24 is for notification bar on Android*/
    final double itemHeight = (size.height - kToolbarHeight - 24) / 2;
    final double itemWidth = size.width / 2;

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Container(
        child: new GridView.count(
          crossAxisCount: 2,
          childAspectRatio: (itemWidth / itemHeight),
          controller: new ScrollController(keepScrollOffset: false),
          shrinkWrap: true,
          scrollDirection: Axis.vertical,
          children: widgetList.map((String value) {
            return new Container(
              color: Colors.green,
              margin: new EdgeInsets.all(1.0),
              child: new Center(
                child: new Text(
                  value,
                  style: new TextStyle(
                    fontSize: 50.0,
                    color: Colors.white,
                  ),
                ),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}

Cảm ơn về câu trả lời. Đã tiết kiệm cho tôi một giờ
Dhruvam Sharma

GridView không có thuộc tính childAspectRatio trừ khi bạn đang thực hiện theo cách đếm: - /
Oliver Dixon

1
@OliverDixon nếu bạn đang sử dụng GridView.builderSliverGridDelegateWithFixedCrossAxisCountsau đó childAspectRatiođang ở trêngridDelegate
Fifer Sheep

làm thế nào để làm cho chiều cao này động?
Dani

12

Cách đây vài ngày, tôi đã đến đây để tìm cách thay đổi chiều cao động khi hình ảnh được tải từ internet và việc sử dụng childAspectRatiokhông thể thực hiện được điều đó vì nó áp dụng cho tất cả tiện ích con trong GridView (cùng chiều cao cho từng).

Câu trả lời này có thể giúp ích cho những ai muốn có chiều cao khác nhau theo từng nội dung widget:

Tôi đã tìm thấy một gói có tên Flutter Stprisred GridView của Romain Rastel . Sử dụng gói này, chúng tôi có thể làm rất nhiều thứ, hãy kiểm tra các ví dụ ở đây.

Để có được những gì chúng tôi muốn, chúng tôi có thể sử dụng StaggeredGridView.count()và thuộc tính của nó staggeredTiles:và vì giá trị của nó, bạn có thể ánh xạ tất cả các widget và áp dụng StaggeredTile.fit(2).

Mã ví dụ:

StaggeredGridView.count(
    crossAxisCount: 4, // I only need two card horizontally
    padding: const EdgeInsets.all(2.0),
    children: yourList.map<Widget>((item) {
      //Do you need to go somewhere when you tap on this card, wrap using InkWell and add your route
      return new Card(
        child: Column(
          children: <Widget>[
             Image.network(item.yourImage),
             Text(yourList.yourText),//may be the structure of your data is different
          ],
        ),
      );
    }).toList(),

    //Here is the place that we are getting flexible/ dynamic card for various images
    staggeredTiles: yourList.map<StaggeredTile>((_) => StaggeredTile.fit(2))
        .toList(),
    mainAxisSpacing: 3.0,
    crossAxisSpacing: 4.0, // add some space
  ),
);

Bạn có thể tìm thấy ví dụ hoàn chỉnh (sao chép, dán và chạy) tại đây .


6

crossAxisCount, crossAxisSpacingVà màn hình độ rộng xác định width, và childAspectRatioxác địnhheight .

Tôi đã tính toán một chút để tìm ra mối quan hệ giữa chúng.

var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var height = width / _aspectRatio;

Ví dụ đầy đủ:

double _crossAxisSpacing = 8, _mainAxisSpacing = 12, _aspectRatio = 2;
int _crossAxisCount = 2;

@override
Widget build(BuildContext context) {
  double screenWidth = MediaQuery.of(context).size.width;

  var width = (screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
  var height = width / _aspectRatio;

  return Scaffold(
    body: GridView.builder(
      itemCount: 10,
      itemBuilder: (context, index) => Container(color: Colors.blue[((index) % 9) * 100]),
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: _crossAxisCount,
        crossAxisSpacing: _crossAxisSpacing,
        mainAxisSpacing: _mainAxisSpacing,
        childAspectRatio: _aspectRatio,
      ),
    ),
  );
}

1

nhập mô tả hình ảnh ở đây

Nó làm việc cho tôi.

Mã ví dụ:

var _crossAxisSpacing = 8;
var _screenWidth = MediaQuery.of(context).size.width;
var _crossAxisCount = 2;
var _width = ( _screenWidth - ((_crossAxisCount - 1) * _crossAxisSpacing)) / _crossAxisCount;
var cellHeight = 60;
var _aspectRatio = _width /cellHeight;

Chế độ hiển thị theo ô:

         GridView.builder(
                          padding: EdgeInsets.only(
                              left: 5.0, right: 5.0, top: 10, bottom: 10),
                          shrinkWrap: false,
                          itemCount: searchList.length,
                          gridDelegate:
                              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: _crossAxisCount,childAspectRatio: _aspectRatio),
                          itemBuilder: (context, index) {
                            final item = searchList[index];
                            return Card(
                              child: ListTile(
                                title: Text(item.name,maxLines: 1,overflow: TextOverflow.ellipsis),
                                trailing: Container(
                                  width: 15,
                                  height: 15,
                                  decoration: BoxDecoration(
                                      color: item.isActive == true
                                          ? Theme.of(context).primaryColor
                                          : Colors.red,
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(50))),
                                ),
                                onTap: () {

                                },
                              ),
                              elevation: 0.5,
                            );
                          },
                        ) 
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.