GridView网格布局 - 鸿蒙Flutter商品展示应用 概述GridView是Flutter中用于展示网格布局的组件适合商品列表、图片画廊等场景。GridView提供了多种构造方式可以灵活地控制网格的列数、宽高比等属性。GridView构造函数GridView.count通过指定列数创建网格GridView.count({Key?key,AxisscrollDirectionAxis.vertical,bool reversefalse,ScrollController?controller,bool?primary,ScrollPhysics?physics,EdgeInsetsGeometry?padding,bool shrinkWrapfalse,required int crossAxisCount,// 列数double mainAxisSpacing0,// 主轴间距double crossAxisSpacing0,// 交叉轴间距double childAspectRatio1,// 宽高比bool addAutomaticKeepAlivestrue,bool addRepaintBoundariestrue,bool addSemanticIndexestrue,int?semanticChildCount,requiredListWidgetchildren,// 子组件列表})GridView.extent通过指定最大宽度创建网格GridView.extent({Key?key,AxisscrollDirectionAxis.vertical,bool reversefalse,ScrollController?controller,bool?primary,ScrollPhysics?physics,EdgeInsetsGeometry?padding,bool shrinkWrapfalse,required double maxCrossAxisExtent,// 最大宽度double mainAxisSpacing0,double crossAxisSpacing0,double childAspectRatio1,bool addAutomaticKeepAlivestrue,bool addRepaintBoundariestrue,bool addSemanticIndexestrue,int?semanticChildCount,requiredListWidgetchildren,})GridView.builder懒加载模式适合大数据网格GridView.builder({Key?key,AxisscrollDirectionAxis.vertical,bool reversefalse,ScrollController?controller,bool?primary,ScrollPhysics?physics,EdgeInsetsGeometry?padding,bool shrinkWrapfalse,requiredSliverGridDelegategridDelegate,// 网格代理requiredIndexedWidgetBuilderitemBuilder,// 项构建器int?itemCount,bool addAutomaticKeepAlivestrue,bool addRepaintBoundariestrue,bool addSemanticIndexestrue,int?semanticChildCount,})核心属性详解crossAxisCount指定列数只在GridView.count中使用crossAxisCount:2,// 2列maxCrossAxisExtent指定子组件的最大宽度只在GridView.extent中使用maxCrossAxisExtent:200,// 每个子组件最大宽度200mainAxisSpacing主轴方向的间距mainAxisSpacing:10,// 垂直方向间距10像素crossAxisSpacing交叉轴方向的间距crossAxisSpacing:10,// 水平方向间距10像素childAspectRatio子组件的宽高比childAspectRatio:1,// 正方形childAspectRatio:1.5,// 宽大于高childAspectRatio:0.66,// 高大于宽gridDelegate网格代理用于自定义网格布局常用SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent// 固定列数gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,mainAxisSpacing:10,crossAxisSpacing:10,childAspectRatio:1,),// 固定最大宽度gridDelegate:constSliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent:200,mainAxisSpacing:10,crossAxisSpacing:10,childAspectRatio:1,),基本用法示例GridView.countGridView.count(crossAxisCount:2,padding:EdgeInsets.all(16),mainAxisSpacing:10,crossAxisSpacing:10,children:[Container(color:Colors.blue[100],child:constCenter(child:Text(Item 1))),Container(color:Colors.green[100],child:constCenter(child:Text(Item 2))),Container(color:Colors.orange[100],child:constCenter(child:Text(Item 3))),Container(color:Colors.purple[100],child:constCenter(child:Text(Item 4))),],)GridView.extentGridView.extent(maxCrossAxisExtent:150,padding:EdgeInsets.all(16),mainAxisSpacing:10,crossAxisSpacing:10,children:[Container(color:Colors.blue[100],child:constCenter(child:Text(Item 1))),Container(color:Colors.green[100],child:constCenter(child:Text(Item 2))),Container(color:Colors.orange[100],child:constCenter(child:Text(Item 3))),Container(color:Colors.purple[100],child:constCenter(child:Text(Item 4))),],)GridView.builderGridView.builder(gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,mainAxisSpacing:10,crossAxisSpacing:10,),itemCount:100,itemBuilder:(context,index){returnContainer(color:Colors.grey[200],child:Center(child:Text(Item$index)),);},)商品列表实战基础商品网格GridView.count(crossAxisCount:2,padding:EdgeInsets.all(16),mainAxisSpacing:12,crossAxisSpacing:12,childAspectRatio:0.7,children:[_buildProductCard(商品1,¥99),_buildProductCard(商品2,¥199),_buildProductCard(商品3,¥299),_buildProductCard(商品4,¥399),],)Widget_buildProductCard(Stringname,Stringprice){returnCard(elevation:2,child:Padding(padding:EdgeInsets.all(8),child:Column(children:[Expanded(child:Container(color:Colors.grey[200],child:constIcon(Icons.shopping_bag,size:48),),),SizedBox(height:8),Text(name,style:TextStyle(fontWeight:FontWeight.bold)),SizedBox(height:4),Text(price,style:TextStyle(color:Colors.red)),],),),);}商品列表全屏布局GridView.builder(gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2,mainAxisSpacing:8,crossAxisSpacing:8,childAspectRatio:0.8,),padding:EdgeInsets.all(8),itemCount:50,itemBuilder:(context,index){returnCard(child:Column(children:[Expanded(child:Container(color:Colors.blue[100],child:Center(child:Text(商品$index)),),),Padding(padding:EdgeInsets.all(8),child:Column(children:[Text(商品名称$index,style:TextStyle(fontWeight:FontWeight.bold)),SizedBox(height:4),Text(¥${(index1)*10},style:TextStyle(color:Colors.red)),],),),],),);},)图片画廊实战图片网格布局GridView.extent(maxCrossAxisExtent:150,padding:EdgeInsets.all(8),mainAxisSpacing:8,crossAxisSpacing:8,children:List.generate(20,(index){returnContainer(decoration:BoxDecoration(color:Colors.grey[200],borderRadius:BorderRadius.circular(8),),child:Center(child:Icon(Icons.image,size:48)),);}),)三种构造方式对比特性GridView.countGridView.extentGridView.builder创建方式固定列数固定最大宽度懒加载适合场景固定列数布局响应式布局大量数据内存占用较高较高较低性能一般一般优异性能优化策略使用GridView.builder对于大量数据使用GridView.builder进行懒加载GridView.builder(gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),itemCount:1000,itemBuilder:(context,index){returnText(Item$index);},)设置childAspectRatio设置合适的宽高比避免不必要的测量childAspectRatio:0.7,// 商品卡片常用比例优化子组件确保子组件是轻量级的GridView.builder(gridDelegate:constSliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2),itemCount:1000,itemBuilder:(context,index){returnContainer(child:constIcon(Icons.image),);},)关键要点总结crossAxisCount指定列数GridView.countmaxCrossAxisExtent指定最大宽度GridView.extentmainAxisSpacing和crossAxisSpacing控制间距childAspectRatio控制宽高比GridView.builder适合大数据网格gridDelegate用于自定义网格布局常见问题Q1: 如何实现响应式网格A: 使用GridView.extent根据屏幕宽度自动调整列数。Q2: 如何设置不同的列数A: 使用SliverGridDelegateWithFixedCrossAxisCount并动态设置crossAxisCount。Q3: 大数据网格卡顿怎么办A: 使用GridView.builder进行懒加载。Q4: 如何控制子组件大小A: 通过childAspectRatio和容器尺寸控制。实践建议固定列数使用GridView.count响应式布局使用GridView.extent大量数据使用GridView.builder商品列表设置childAspectRatio为0.7~0.8图片画廊设置childAspectRatio为1正方形通过合理使用GridView的各种构造方式和属性可以创建出高效、美观的网格布局满足商品展示、图片画廊等多种应用场景的需求。