如何设置 gridview child 的宽度以匹配屏幕宽度?

How to set width of child of gridview to match screen width?

我有 GridView,其 crossAxisCount 为 2。我希望 child 或 GridView 的宽度与屏幕宽度的一半相同,同时保持正确的纵横比比率。 我的代码 GridView.

Container(
          child: GridView.builder(
            scrollDirection: Axis.vertical,
            gridDelegate:
                SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2,
                ),
            shrinkWrap: true,
            padding: EdgeInsets.all(8),
            itemCount: albumsCovers.length,
            itemBuilder: (BuildContext context, int index) {
              return MyCard(
                imageName: albumsCovers.elementAt(index),
                text1: albumNames.elementAt(index),
                text2: albumNames.elementAt(index),
              );
            },
          ),
        ),

我的自定义小部件的代码。我用 Row 包装了我的 Image 因为没有 Row 小部件 Image 小部件不会扩展到 GridView child 可用的最大宽度。

class MyCard extends StatelessWidget {

  final String imageName;
  final String text1,text2;

  MyCard({this.imageName,this.text1,this.text2});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(8),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
       //without Row widget Image widget does not expand to the max available size to GridView child.
          Row(
            children: [
              Expanded(
                child: Image(image: AssetImage(this.imageName),),
              ),
            ],
          ),
          SizedBox(height: 8),
          Text(
            this.text1,
            overflow: TextOverflow.ellipsis,
            softWrap: false,
            maxLines: 1,
            style: TextStyle(
              fontSize: 16,
              color: Colors.white,
              fontWeight: FontWeight.bold,
            ),
          ),
          Text(
            this.text2,
            overflow: TextOverflow.ellipsis,
            softWrap: false,
            maxLines: 1,
            style: TextStyle(
              fontSize: 14,
              color: Color(0xFF8E8E8E),
            ),
          ),
        ],
      ),
    );
  }
}

我希望我的 GridView 看起来像这样。但是我在 Image 下面的 Text 被切掉了, Flutter 显示底部溢出。 注意:我已经有长宽比为 1:1 的图像。 这就是单个 MyCard 的样子。

这是 GridView 的预期外观。

尝试(修复纵横比,不需要行)

class MyCard extends StatelessWidget {
  final String imageName;
  final String text1, text2;

  MyCard({this.imageName, this.text1, this.text2});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(8),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Expanded(
            child: AspectRatio(
              aspectRatio: 1 / 1,
              child: Container(
                color: Colors.red,
                child: Center(child: Text('Image $imageName')),
              ),
            ),
          ),
          SizedBox(height: 8),
          Text(
            this.text1,
            overflow: TextOverflow.ellipsis,
            softWrap: false,
            maxLines: 1,
            style: TextStyle(
              fontSize: 16,
              color: Colors.green,
              fontWeight: FontWeight.bold,
            ),
          ),
          Text(
            this.text2,
            overflow: TextOverflow.ellipsis,
            softWrap: false,
            maxLines: 1,
            style: TextStyle(
              fontSize: 14,
              color: Color(0xFF8E8E8E),
            ),
          ),
        ],
      ),
    );
  }
}

你应该删除 ExpandedRow 然后使用一个 Image 属性 调用 fit 然后调用这个 BoxFit 这里是代码

     Container(
              decoration: BoxDecoration(color: Colors.grey),
              child: AspectRatio(
                aspectRatio: 300 / 200,
                child: Image.asset(
                  '${widget.imageP}',
                  fit: BoxFit.cover,
                ),
              ),
            ),

我刚刚计算了每个 Text 小部件的高度并设置了 childAspectRatio:itemWidth / itemHeight,如@Assassin 所述。 计算Text.

的高度
final TextStyle textStyle14 = TextStyle(
    fontSize: 14,
    color: Colors.white,
  );
  final TextStyle textStyle16 = TextStyle(
    fontSize: 16,
    color: Colors.white,
    fontWeight: FontWeight.bold,
  );

  Size _textSize(String text,TextStyle textStyle,BuildContext context)=> (TextPainter(
      text: TextSpan(text: text, style: textStyle),
      maxLines: 1,
      textScaleFactor: MediaQuery.of(context).textScaleFactor,
      textDirection: TextDirection.ltr)
    ..layout())
      .size;

build 函数内部:

var size = MediaQuery.of(context).size;

    //subtracting margin value from screen width
    final double itemWidth = size.width*(0.5)-8;
    // height of image is same as width of image. so itemHeight = itemWidth + (height of 2 Text+8 margin)
    final double itemHeight = itemWidth +(_textSize('Text', textStyle14,context).height.ceil() + _textSize('Text', textStyle16,context).height.ceil()+8);

GridView 代码:

Container(
          child: GridView.builder(
            scrollDirection: Axis.vertical,
            physics: NeverScrollableScrollPhysics(),
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              childAspectRatio: (itemWidth / itemHeight),
            ),
            shrinkWrap: true,
            padding: EdgeInsets.all(8),
            itemCount: albumsCovers.length,
            itemBuilder: (BuildContext context, int index) {
              return MadeForUCard(
                imageName: albumsCovers.elementAt(index),
                text1: albumNames.elementAt(index),
                text2: albumNames.elementAt(index),
              );
            },
          ),
        ),