Flutter 页面布局 GridView网格布局
	
	GridView是 Flutter 中用于创建网格布局的强大小部件。它允许你在行和列中排列子小部件,非常适合显示大量项目,例如图像、文本、卡片等
	
      如下图所示可见,GridView网格布局在app中的使用频率其实非常高,所以接下来就让我们来看看在Flutter中如何使用吧~

初识GridView
GridView一共有5个构造函数:GridView,GridView.builder,GridView.count,GridView.extent和GridView.custom。但是不用慌,因为可以说其实掌握其默认构造函数就都会了。
GridView 提供了几种构造函数来创建不同类型的网格布局:
1、GridView:最通用的构造函数,完全自定义网格布局。
2、GridView.builder:按需构建网格项,适用于具有大量(或无限)网格项的动态内容。
3、GridView.count:指定网格中的列数,适用于具有固定数量列的网格。
4、GridView.extent:指定网格中最大交叉轴范围(例如,最大列宽),适用于需要控制列宽的网格。
5、GridView.custom:这个构造函数提供了最高级别的自定义能力,允许使用自定义的SliverGridDelegate和SliverChildDelegate。
主要介绍两种
1、可以通过 GridView.count 实现网格布局
2、通过 GridView.builder 实现网格布局
GridView是一个可滚动的view,也就是ScrollView,事实上GridView继承自BoxScrollView:
GridView常用属性:
| 属性 | 说明 | 
| scrollDirection | 滚动方向 | 
| reverse | 组件反向排序 | 
| controller | 滚动控制(滚动监听) | 
| primary | 如果内容不足,则用户无法滚动 而如果[primary]为true,它们总是可以尝试滚动。 | 
| physics |   滑动类型设置  AlwaysScrollableScrollPhysics() 总是可以滑动  NeverScrollableScrollPhysics禁止滚动  BouncingScrollPhysics 内容超过一屏 上拉有回弹效果  ClampingScrollPhysics 包裹内容 不会有回弹   | 
| shrinkWrap | 默认false   内容适配 | 
| padding | 内边距 | 
| crossAxisCount | 列 数量 | 
| mainAxisSpacing | 垂直子 Widget 之间间距 | 
| crossAxisSpacing | 水平子 Widget 之间间距 | 
| childAspectRatio | 子 Widget 宽高比例 | 
| addAutomaticKeepAlives | 默认true | 
| addRepaintBoundaries | 默认true | 
| addSemanticIndexes | 默认true | 
| cacheExtent | 设置预加载的区域 | 
| children | 子元素 | 
| semanticChildCount | 将提供语义信息的子代数量 | 
| dragStartBehavior |   | 
| GridView.builder独有属性 |   | 
| gridDelegate | 一个控制 GridView 中子项布局的委托。 | 
| itemBuilder | 遍历数返回Widget | 
| itemCount | 子控件数量 | 
GridView.count 实现网格布局
● GridView.count 接收下面的命名参数:
● crossAxisCount 是必传的,用来控制横轴上子项的个数
● crossAxisSpacing 用来指定横轴上两列的宽度间隙
● mainAxisSpacing 用来指定纵轴上两行的高度间隙
● childAspectRatio宽高比
		
			
				
//网格布局演示
class GridView_test extends StatelessWidget{
  List _initlistdata(){
    List tmplist=[];    //创建一个存储widget的列表
    for(var i=0; i<list.length; i++){    //list为接收到的数据,在头文件引入
      tmplist.add(Container(
        alignment: Alignment.bottomRight,
        decoration: BoxDecoration(
          border: Border.all(color: Colors.red,width: 2),   //设置边框
           //设置图片填充方式
        ),
        child:Column(
          children: [
            Image(image: NetworkImage("${list[i]["cover"]}")), //设置显示图片
            const SizedBox(height: 10,),
            Text("${list[i]["name"]}",)//设置文字
          ],
        ),
      ),
      );
    }
    return tmplist;
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return GridView.count(
        crossAxisCount: 3,  //设置一行的个数
        crossAxisSpacing:10,  //设置列间距
        mainAxisSpacing: 10, //设置行间距
      children:_initlistdata()
    );
  }
}
				 
			 
		 
	 
 
GridView.builder实现动态列表
当子widget较多时可以使用该方法来动态创建子widget,在使用GridView.builder时有两个比传入参数gridDelegate与itemBuilder
● gridDelegate是SliverGridDelegate类型,主要是用来控制GridView的子Widget的样式
● itemBuilder方法接收context和index两个参数,返回widget即可
		
			
				
//网格布局演示二
class Gridview_test2 extends StatelessWidget{
  Widget _initlistdata(context,index){
    return Container(
        alignment: Alignment.bottomRight,
        decoration: BoxDecoration(
          border: Border.all(color: Colors.red,width: 2),   //设置边框
          //设置图片填充方式
        ),
        child:Column(
          children: [
            Image(image: NetworkImage("${list[index]["cover"]}")), //设置显示图片
            const SizedBox(height: 10,),
            Text("${list[index]["name"]}",)//设置文字
          ],
        ),
      );
    }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return GridView.builder(
        itemCount: list.length,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2
    ), itemBuilder: _initlistdata);
  }
}