一、问题场景
我们在使用GridView的时候 child在列表中所占大小宽高是一致的,但是往往我们需求不是的。
二、解决方案
方案一 每个孩子的横轴与主轴范围的比率。 child的宽高比childAspectRatio
var itemWidth = (MediaQuery.of(context).size.width - 30) / 2;
var itemHeight = 255.0;
childAspectRatio = itemWidth / itemHeight;
GridView.builder(
padding: EdgeInsets.all(0),
itemCount: itemList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
/// 纵轴间距
mainAxisSpacing: 10.0,
/// 横轴间距
crossAxisSpacing: 10.0,
/// 横轴元素个数
crossAxisCount: 2,
/// 宽高比
childAspectRatio: childAspectRatio,
),
itemBuilder: (context, index) =>
GoodsItemWidget(itemList[index])),
方案二 继承 SliverGridDelegate,来重写它的布局
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class SliverGridDelegateWithFixedSize extends SliverGridDelegate {
/// 宽
final double width;
/// 高
final double height;
/// 纵轴间距
final double mainAxisSpacing;
/// 横轴间距
final double crossAxisSpacing;
SliverGridDelegateWithFixedSize(this.width, this.height,
{this.mainAxisSpacing = 0.0, this.crossAxisSpacing = 0.0});
@override
SliverGridLayout getLayout(SliverConstraints constraints) {
final crossAxisCount = constraints.crossAxisExtent ~/ width;
final crossAxisSpacing;
if (this.crossAxisSpacing == 0.0) {
crossAxisSpacing =
(constraints.crossAxisExtent - width * crossAxisCount) /
(crossAxisCount - 1);
} else {
crossAxisSpacing = this.crossAxisSpacing;
}
return SliverGridRegularTileLayout(
crossAxisCount: crossAxisCount,
mainAxisStride: height + mainAxisSpacing,
crossAxisStride: width + crossAxisSpacing,
childMainAxisExtent: height,
childCrossAxisExtent: width,
reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
}
@override
bool shouldRelayout(SliverGridDelegateWithFixedSize oldDelegate) {
return oldDelegate.width != width ||
oldDelegate.height != height ||
oldDelegate.mainAxisSpacing != mainAxisSpacing;
}
}
示例
GridView.builder(
padding: EdgeInsets.all(0),
itemCount: itemList.length,
gridDelegate: SliverGridDelegateWithFixedSize(
itemWidth,
itemHeight,
mainAxisSpacing: mainAxisSpacing,
),
itemBuilder: (context, index) =>
GoodsItemWidget(itemList[index])),