【问题标题】:How to set width of child of gridview to match screen width?如何设置gridview的孩子的宽度以匹配屏幕宽度?
【发布时间】:2021-02-14 06:00:26
【问题描述】:

我有GridView,其crossAxisCount 为2。我希望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 子可用的最大宽度。

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 的预期外观。

【问题讨论】:

  • 尝试childAspectRatio:itemWidth / itemHeightSliverGridDelegateWithFixedCrossAxisCount中使用,在gridview@user11862325中使用自定义itemwidth和itemHeight
  • @Assassin itemWidth 总是屏幕大小的一半,所以我可以轻松获得itemWidth。但是我如何才能得到itemHeight?Text会根据不同的手机尺寸和用户的喜好有不同的尺寸。
  • 你试过MediaQuerymedium.com/tagmalogic/…@user11862325
  • @Assassin 我读过你提到的那篇文章。但这仍然不能解决我的问题。我知道我可以通过计算(0.5)*MediaQuery.of(context).size.width 得到itemWidth。和 itemHeight 将是 itemHeight = itemWidth + (height of the 2 Text widget + 8) 这根本不依赖于屏幕高度。

标签: flutter gridview flutter-layout


【解决方案1】:

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

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

【讨论】:

  • 我想你误解了我的问题。我有宽高比已经是 1:1 的图像。所以我使用了图像小部件。我希望它们看起来像我上传的图片(图片的宽度为屏幕宽度的一半。)
  • 你试过了吗。它做你想做的事。
  • 它不再在底部溢出,但Image 尺寸减小了。(Image 的宽度不是我需要的屏幕尺寸的一半。)
【解决方案2】:

您应该删除ExpandedRow,然后使用名为fitImage 属性,然后调用此BoxFit 这是代码

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

【讨论】:

    【解决方案3】:

    我刚刚计算了每个Text 小部件的高度,并按照@Assassin 的说明设置了childAspectRatio:itemWidth / itemHeight。 计算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),
                  );
                },
              ),
            ),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多