如何设置gridview的孩子的宽度以匹配屏幕宽度?
Posted
技术标签:
【中文标题】如何设置gridview的孩子的宽度以匹配屏幕宽度?【英文标题】:How to set width of child of gridview to match screen width? 【发布时间】: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 / itemHeight
在SliverGridDelegateWithFixedCrossAxisCount
中使用,在gridview@user11862325中使用自定义itemwidth和itemHeight
@Assassin itemWidth
总是屏幕大小的一半,所以我可以轻松获得itemWidth
。但是我如何才能得到itemHeight
?Text
会根据不同的手机尺寸和用户的喜好有不同的尺寸。
你试过MediaQuery
medium.com/tagmalogic/…@user11862325
@Assassin 我读过你提到的那篇文章。但这仍然不能解决我的问题。我知道我可以通过计算(0.5)*MediaQuery.of(context).size.width
得到itemWidth
。和 itemHeight
将是 itemHeight = itemWidth + (height of the 2 Text widget + 8)
这根本不依赖于屏幕高度。
【参考方案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】:
您应该删除Expanded
和Row
,然后使用名为fit
的Image
属性,然后调用此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),
);
,
),
),
【讨论】:
以上是关于如何设置gridview的孩子的宽度以匹配屏幕宽度?的主要内容,如果未能解决你的问题,请参考以下文章
Android GridView——如何以dp单位使用setColumnWidth()设置宽度