如何在Flutter中为GridView.builder计算childAspectRatio
如何在Flutter中为GridView.builder计算childAspectRatio
带有图像和类别名称的类别网格显示在图像下方:
Widget build(BuildContext context) {
return FutureBuilder(
future: categoriesService.getCategories(1),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.error != null) {
print('error ${snapshot.error}');
return Text(snapshot.error.toString());
}
// 在这里添加您的自定义代码
return Container(
// padding: const EdgeInsets.all(0.0),
child: GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
// childAspectRatio: 19 / 12,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Category category = snapshot.data[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children:
Expanded(
child: Container(
child: Image.network(
category.image,
fit: BoxFit.cover,
),
decoration: BoxDecoration(
border: Border.all(width: 1.0),
),
),
),
SizedBox(height: 5.0),
Text(
category.name,
textAlign: TextAlign.center,
)
],
);
},
),
);
} else {
return CircularProgressIndicator();
}
},
);
}
我的子项包含图像和类别名称。如图所示,当前子项溢出,并且我们无法看到图像下方的类别名称,并且无法删除图像和边框之间的顶部空间。
原始设计在此处:
[https://i.stack.imgur.com/54Vhy.png](https://i.stack.imgur.com/54Vhy.png)
问题:
在Flutter中,使用GridView.builder时,如何计算childAspectRatio?
解决方法:
有一个方便解决这个问题的Flutter包。可以在https://pub.dev/packages/dynamic_height_grid_view查看。使用这个包可以指定交叉轴数量而不考虑纵横比。
易于使用和配置
应该标记为正确答案。
问题的出现原因:
该问题的出现原因是作者想要在Flutter中的GridView.builder中动态设置最大子项的宽高比(childAspectRatio)。
解决方法:
作者提供了一个解决方法,通过获取子项的尺寸并计算出宽高比,然后将宽高比应用于GridView.builder的childAspectRatio属性。
具体实现步骤如下:
1. 声明一个GridItemModel类,该类包含一个长文本(longtext)和一个全局键(itemKey)。在构造函数中初始化itemKey。
2. 在MyHomePage类的initState方法中,创建一个OverlayEntry对象并通过addPostFrameCallback方法将其插入到Overlay中。在OverlayEntry的builder方法中调用stickyBuilder方法。
3. 在stickyBuilder方法中,遍历myGridList列表,如果子项的宽度为空,则通过itemKey获取子项的尺寸并赋值给width和height。然后调用shouldUpdateGridList方法。
4. 在shouldUpdateGridList方法中,遍历myGridList列表,如果子项的宽度不为空,则比较子项的高度与maxHeight的大小,如果大于maxHeight,则更新maxHeight和maxWidth,并将isChanged设置为true。最后根据maxWidth和maxHeight计算出宽高比myDynamicAspectRatio,并将其打印出来。
5. 在MyHomePage类的build方法中,创建一个GridView.count组件,并设置crossAxisCount为2,childAspectRatio为myDynamicAspectRatio。通过List.generate方法生成20个子项,并将其添加到myGridList列表中。
6. 最后,在Scaffold组件的body属性中返回GridView.count组件。
还有一个示例代码,可以通过点击这里进行查看。
最后,作者表示该方法尚未解决他的问题,他希望能够显示1:1的图像,并在每个图像的底部添加一个宽度为100像素的容器。他希望得到解决方法。
在GridView.builder中计算childAspectRatio的方法是根据设备的宽度和高度动态计算。下面是一个基于您的代码示例的示例代码,显示了如何实现这一点。请注意,为了适应特定的要求,您可能需要微调提供的宽高比。
您可能会发现下面的答案对于有关GridView小部件的宽高比的其他信息很有用,如果您还没有看到它们的话。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class Category {
String name;
String image;
Category({this.name, this.image});
}
class CategoriesService {
Future> getCategories(int value) async {
return
Category(
name: 'FRESH CHICKEN',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'FRESH MUTTON',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'HALAL FROZEN FISH',
image: 'https://picsum.photos/400/300',
),
Category(
name: '2X STORE',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'FROZEN NONVEG DELIGHTS',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'FROZEN VEG DELIGHTS',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'DAL & PULSES',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'SPICES',
image: 'https://picsum.photos/400/300',
),
Category(
name: 'DRY FRUITS & NUTS',
image: 'https://picsum.photos/400/300',
),
];
}
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: CategoriesService().getCategories(1),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.error != null) {
print('error ${snapshot.error}');
return Text(snapshot.error.toString());
}
// YOUR CUSTOM CODE GOES HERE
return Container(
child: GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.4),
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Category category = snapshot.data[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children:
Container(
child: Image.network(
category.image,
fit: BoxFit.cover,
),
decoration: BoxDecoration(
border: Border.all(width: 1.0),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
),
child: Text(
category.name,
textAlign: TextAlign.center,
),
)
],
);
},
),
);
} else {
return CircularProgressIndicator();
}
},
),
),
);
}
}
您的问题是如何在1:1(宽度:高度)比例下显示网格,但是高度应该额外增加100个像素。请问有什么建议吗?谢谢。
参考链接:
- [How to set Custom height for Widget in GridView in Flutter?](https://stackoverflow.com/questions/48405123)
- [How to set grid view column height?](https://stackoverflow.com/questions/50602425)
- [flutter how to give height to the childrens of GridView.Builder](https://stackoverflow.com/questions/53612200)