Flutter GridView详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hao_m582/article/details/84147315

GridView常用构造

GridView

构造函数
GridView({Key key, Axis scrollDirection: Axis.vertical, bool reverse: false,
 ScrollController controller, bool primary, 
 ScrollPhysics physics, bool shrinkWrap: false,
  EdgeInsetsGeometry padding, 
 @required SliverGridDelegate gridDelegate, 
 bool addAutomaticKeepAlives: true,
  bool addRepaintBoundaries: true, 
 bool addSemanticIndexes: true,
  double cacheExtent, List<Widget> children: const [], 
  int semanticChildCount })
  
Creates a scrollable, 2D array of widgets with a custom SliverGridDelegate. [...]

GridView.count

构造函数
GridView.count({Key key, Axis scrollDirection: Axis.vertical, 
bool reverse: false, ScrollController controller, 
bool primary, ScrollPhysics physics, bool shrinkWrap: false, 
EdgeInsetsGeometry padding, @required int crossAxisCount,
 double mainAxisSpacing: 0.0, double crossAxisSpacing: 0.0, 
 double childAspectRatio: 1.0, bool addAutomaticKeepAlives: true,
  bool addRepaintBoundaries: true, 
  bool addSemanticIndexes: true,
   double cacheExtent, List<Widget> children: const [], 
   int semanticChildCount })
   
Creates a scrollable, 2D array of widgets with a fixed number of 
tiles in the cross axis. [...]
分析和使用
 Widget gridViewDefaultCount(List<BaseBean> list) {
    return GridView.count(
//      padding: EdgeInsets.all(5.0),
      //一行多少个
      crossAxisCount: 5,
      //滚动方向
      scrollDirection: Axis.vertical,
      // 左右间隔
      crossAxisSpacing: 10.0,
      // 上下间隔
      mainAxisSpacing: 10.0,
      //宽高比
      childAspectRatio: 2 / 5,

      children: initListWidget(list),
    );
  }

List<Widget> initListWidget(List<BaseBean> list) {
    List<Widget> lists = [];
    for (var item in list) {
      lists.add(new Container(
        height: 50.0,
        width: 50.0,
        color: Colors.yellow,
        child: new Center(
            child: new Text(
          item.age.toString(),
        )),
      ));
    }
    return lists;
  }

GridView.extent

构造函数
GridView.extent({Key key, Axis scrollDirection: Axis.vertical,
 bool reverse: false, ScrollController controller,
  bool primary, ScrollPhysics physics, 
  bool shrinkWrap: false, EdgeInsetsGeometry padding,
   @required double maxCrossAxisExtent,
    double mainAxisSpacing: 0.0, double crossAxisSpacing: 0.0,
     double childAspectRatio: 1.0, 
     bool addAutomaticKeepAlives: true,
      bool addRepaintBoundaries: true, 
      bool addSemanticIndexes: true,
       List<Widget> children: const [], 
       int semanticChildCount })
       
Creates a scrollable, 2D array of widgets with tiles that 
each have a maximum cross-axis extent. [...]
分析和使用
 ///GridView.extent 允许您指定项的最大像素宽度
  Widget gridViewDefaultExtent(List<BaseBean> list) {
    return GridView.extent(
      ///设置item的最大像素宽度  比如 130
      maxCrossAxisExtent: 130.0,

      ///其他属性和count一样
      children: initListWidget(list),
    );
  }

GridView.builder

构造函数
GridView.builder({Key key, Axis scrollDirection: Axis.vertical,
 bool reverse: false, ScrollController controller, 
 bool primary, ScrollPhysics physics,
  bool shrinkWrap: false, EdgeInsetsGeometry padding, 
  @required SliverGridDelegate gridDelegate, 
  @required IndexedWidgetBuilder itemBuilder,
   int itemCount, bool addAutomaticKeepAlives: true,
    bool addRepaintBoundaries: true, 
    bool addSemanticIndexes: true, 
    double cacheExtent, int semanticChildCount })
    
Creates a scrollable, 2D array of widgets that are created on demand. [...]
分析和使用
 ///GridView.builder  可以定义gridDelegate的模式
  Widget gridViewDefaultBuilder(List<BaseBean> list) {
    return GridView.builder(
        gridDelegate: MyGridViewDefaultCustom(
          crossAxisCount: 2,
          mainAxisSpacing: 10.0,
          crossAxisSpacing: 10.0,
          childAspectRatio: 1.0,
        ),
        itemBuilder: (context, i) => new Container(
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  new Text(
                    "${list[i].name}",
                    style: new TextStyle(fontSize: 18.0, color: Colors.red),
                  ),
                  new Text(
                    "${list[i].age}",
                    style: new TextStyle(fontSize: 18.0, color: Colors.green),
                  ),
                  new Text(
                    "${list[i].content}",
                    style: new TextStyle(fontSize: 18.0, color: Colors.blue),
                  ),
                ],
              ),
            ));
  }
///自定义SliverGridDelegate
class MyGridViewDefaultCustom extends SliverGridDelegate {
  ///横轴上的子节点数。  一行多少个child
  final int crossAxisCount;

  ///沿主轴的每个子节点之间的逻辑像素数。 默认垂直方向的子child间距  这里的是主轴方向 当你改变 scrollDirection: Axis.vertical,就是改变了主轴发方向
  final double mainAxisSpacing;

  ///沿横轴的每个子节点之间的逻辑像素数。默认水平方向的子child间距
  final double crossAxisSpacing;

  ///每个孩子的横轴与主轴范围的比率。 child的宽高比  常用来处理child的适配
  final double childAspectRatio;

  bool _debugAssertIsValid() {
    assert(mainAxisSpacing >= 0.0);
    assert(crossAxisSpacing >= 0.0);
    assert(childAspectRatio > 0.0);
    return true;
  }

  const MyGridViewDefaultCustom({
    @required this.crossAxisCount,
    this.mainAxisSpacing = 0.0,
    this.crossAxisSpacing = 0.0,
    this.childAspectRatio = 1.0,
  })  : assert(crossAxisCount != null && crossAxisCount > 0),
        assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
        assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
        assert(childAspectRatio != null && childAspectRatio > 0);

  ///  返回值有关网格中图块大小和位置的信息。这里就是处理怎么摆放 我们可以自己定义
  ///   SliverGridLayout是抽象类  SliverGridRegularTileLayout继承于SliverGridLayout是抽象类
  @override
  SliverGridLayout getLayout(SliverConstraints constraints) {
    // TODO: implement getLayout
    assert(_debugAssertIsValid());

    ///对参数的修饰 自定义
    final double usableCrossAxisExtent =
        constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1);
    final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
    final double childMainAxisExtent = childCrossAxisExtent / childAspectRatio;
    return MySliverGridLayout(
      crossAxisCount: crossAxisCount,
      mainAxisStride: childMainAxisExtent + mainAxisSpacing,
      crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
      childMainAxisExtent: childMainAxisExtent,
      childCrossAxisExtent: childCrossAxisExtent,
      reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
    );
  }

  /// 和ListView的 shouldRebuild 作用一样   之前的实例和新进来的实例是相同的就返回true
  @override
  bool shouldRelayout(SliverGridDelegate oldDelegate) {
    // TODO: implement shouldRelayout
    return true;
  }
}

GridView.custom

构造函数
GridView.custom({Key key, Axis scrollDirection: Axis.vertical,
 bool reverse: false, ScrollController controller, 
 bool primary, ScrollPhysics physics, 
 bool shrinkWrap: false, 
 EdgeInsetsGeometry padding,
  @required SliverGridDelegate gridDelegate,
  @required SliverChildDelegate childrenDelegate, 
  double cacheExtent,
   int semanticChildCount })
   
Creates a scrollable, 2D array of widgets with both a custom
 SliverGridDelegate and a custom SliverChildDelegate. [...]
分析和使用
 ///GridView.custom 就是自己定制规则
  /// 这里说一下 GridView.count gridDelegate 其实就是内部实现 SliverGridDelegateWithFixedCrossAxisCount
  /// GridView.extent gridDelegate 其实就是内部实现 SliverGridDelegateWithMaxCrossAxisExtent
  Widget gridViewDefaultCustom(List<BaseBean> list) {
    return GridView.custom(
      gridDelegate: MyGridViewDefaultCustom(
        crossAxisCount: 2,
        mainAxisSpacing: 10.0,
        crossAxisSpacing: 10.0,
        childAspectRatio: 1.0,
      ),
      childrenDelegate: MyGridChildrenDelegate(
        (BuildContext context, int i) {
          return new Container(
              child: new Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              new Text(
                "${list[i].name}",
                style: new TextStyle(fontSize: 18.0, color: Colors.red),
              ),
              new Text(
                "${list[i].age}",
                style: new TextStyle(fontSize: 18.0, color: Colors.green),
              ),
              new Text(
                "${list[i].content}",
                style: new TextStyle(fontSize: 18.0, color: Colors.blue),
              ),
            ],
          ));
        },
        childCount: list.length,
      ),
    );
  }
/**
 * 继承SliverChildBuilderDelegate  可以对列表的监听
 */
class MyGridChildrenDelegate extends SliverChildBuilderDelegate {
  MyGridChildrenDelegate(
    Widget Function(BuildContext, int) builder, {
    int childCount,
    bool addAutomaticKeepAlive = true,
    bool addRepaintBoundaries = true,
  }) : super(builder,
            childCount: childCount,
            addAutomaticKeepAlives: addAutomaticKeepAlive,
            addRepaintBoundaries: addRepaintBoundaries);

  ///监听 在可见的列表中 显示的第一个位置和最后一个位置
  @override
  void didFinishLayout(int firstIndex, int lastIndex) {
    print('firstIndex: $firstIndex, lastIndex: $lastIndex');
  }

  ///可不重写 重写不能为null  默认是true  添加进来的实例与之前的实例是否相同 相同返回true 反之false
  ///listView 暂时没有看到应用场景 源码中使用在 SliverFillViewport 中
  @override
  bool shouldRebuild(SliverChildBuilderDelegate oldDelegate) {
    // TODO: implement shouldRebuild
    print("oldDelegate$oldDelegate");
    return super.shouldRebuild(oldDelegate);
  }
}

猜你喜欢

转载自blog.csdn.net/hao_m582/article/details/84147315