前端
使用Gap为 Flutter 添加间隙
最近,我希望Row或Column小部件有一个spacing属性来配置子小部件之间的间隙。因为我发现向这些子项添加填充太麻烦了 - 既因为这进一步缩进了小部件树中的小部件,又因为很难决定是否应该仅添加底部填充,或仅添加顶部填充,或同时添加填充子部件的顶部和底部——我最常使用SizedBox部件来引入间隙。还有另一个不便之处:我必须根据是否将间隙添加到or来显式设置widthor属性,并且要使用常量,我必须引入and或 类似的东西。heightRowColumnsmallVerticalGapsmallHorizontalGap我们可以创建一个Gap自动执行正确操作的小部件吗?我们可以!差距这是我的实现。因为它的布局取决于小部件direction的Flex子级(Spacer小部件也有同样的问题),所以仅使用小部件无法实现这一点。我需要一个特殊的渲染对象来执行特殊的布局。因此,Gap应是以下子类SingleChildRenderObjectWidget:class Gap extends SingleChildRenderObjectWidget {
const Gap({Key key, this.size = 16})
: assert(size != null),
super(key: key); final double size; …
Gap现在需要实现一个createRenderObject创建渲染对象的方法。我将RenderGap按照 Flutter 的命名约定将此对象称为。 …… @override
RenderGap createRenderObject(BuildContext context) {
return RenderGap(size);
} ……
由于Gap有一个必须传递的属性,我还实现了updateRenderObject确保对该属性的更改也会影响我的渲染对象: …… @override
void updateRenderObject(BuildContext context, RenderGap renderObject) {
renderObject.gapSize = size;
}
}
它RenderGap作为子类实现RenderBox,提供了所需的大部分功能。因为渲染对象(与小部件相反)是可变的,所以我确保对属性的更改gapSize会触发重新布局,但前提是尺寸确实发生变化。class RenderGap extends RenderBox {
RenderGap(this._gapSize); double _gapSize;
double get gapSize => _gapSize;
set gapSize(double gapSize) {
if (_gapSize != gapSize) {
_gapSize = gapSize;
markNeedsLayout();
}
} …
我们已经完成了样板代码。为了实现布局,我们必须重写performLayout必须设置对象size属性的方法。文档说它也应该尊重对象的constraints,但现在,我忽略它们,因为我有点着急。希望我的假设是正确的,performLayout只有在对象被添加到渲染树后才会被调用,因此总是有一个parent.我根据其父级的布局方向分配大小,如下所示: … @override
void performLayout() {
final parent = this.parent;
if (parent is RenderFlex) {
if (parent.direction == Axis.horizontal) {
size = Size(_gapSize, 0);
} else {
size = Size(0, _gapSize);
}
} else {
throw FlutterError(‘Gap must be used inside a Flex widget’);
}
}
}
现在,可以向列或行添加间隙:Column(
Children: [
Text('这是一条消息'),
Gap.large,
Row(
Children: [
Spacer(),
RaishedButton(
onPressed: () => null,
child: Text('取消'),
),
Gap .small,
RaisingButton(
onPressed: () => null,
child: Text('OK'),
),
],
),
]
);
为了完整的实现,还必须重写这四种compute{Min,Max}Intrinsic{Width,Height}方法。gapSize如果存在带有正确“ ` 的parent类,则它们应该返回而不是 0 。RenderFlexdirection
2024-04-07
58 次阅读