具有使用CustomSingleChildLayout
和CustomSingleChildLayout
类的经验的人可以(使用示例)详细解释如何使用它们。
我是Flutter的新手,正在尝试了解如何使用它们。但是,该文档太糟糕了,不清楚。我尝试在Internet上搜索示例,但没有其他文档。
如果您能提供帮助,我将万分感谢。
谢谢!
首先,我很高兴能为您提供帮助,因为我可以理解您的挣扎-自己解决问题也有好处(文档很棒)。
CustomMultiChildLayout
的作用在我向您解释CustomMultiChildLayout
之后将显而易见。
CustomSingleChildLayout
此小部件的要点是允许您通过单个函数layout传递给此小部件的子代,即,它们的位置和大小可以相互依赖,这是您无法实现的使用例如预建的CustomMultiChildLayout
小部件。
CustomMultiChildLayout
现在,您需要执行另外两个步骤,然后才能开始布置孩子:
CustomMultiChildLayout
的每个孩子都必须是Stack
,然后将实际上要显示为孩子的小部件传递给CustomMultiChildLayout(
children: [
// Widgets you want to layout in a customized manner
],
)
。 children
将唯一地标识您的小部件,从而在布局它们时可以访问它们:LayoutId
LayoutId
子类。这里的文档似乎非常复杂。LayoutId
现在,所有设置都已完成,您可以开始实施实际布局。您可以使用三种方法:
id
,可让您检查是否将特定的id(是否记得CustomMultiChildLayout(
children: [
LayoutId(
id: 1, // The id can be anything, i.e. any Object, also an enum value.
child: Text('Widget one'), // This is the widget you actually want to show.
),
LayoutId(
id: 2, // You will need to refer to that id when laying out your children.
child: Text('Widget two'),
),
],
)
?)传递给MultiChildLayoutDelegate
,即是否存在该ID的孩子。
[MultiChildLayoutDelegate
,您需要为每个id,每个孩子提供一个[[恰好一次]]调用,它将为您提供该孩子的class YourLayoutDelegate extends MultiChildLayoutDelegate {
// You can pass any parameters to this class because you will instantiate your delegate
// in the build function where you place your CustomMultiChildLayout.
// I will use an Offset for this simple example.
YourLayoutDelegate({this.position});
final Offset position;
}
。
hasChild
,可让您将位置从hasChild
更改为您指定的任何偏移量。我觉得现在概念应该很清楚了,这就是为什么我将说明如何为示例LayoutId
实现委托的原因:>
children
另外两个示例是文档中的一个示例(检查准备示例:步骤2
)和一个我为layoutChild
包写了一段时间的real world
layoutChild
和Size
。 最后一步是覆盖positionChild
,它通过与旧的委托进行比较,简单地控制是否应在任何给定时间点再次调用positionChild
,(可选地,您也可以覆盖Offset(0, 0)
)并添加委托到您的CustomMultiChildLayout
:class YourLayoutDelegate extends MultiChildLayoutDelegate {
YourLayoutDelegate({this.position});
final Offset position;
@override
void performLayout(Size size) {
// `size` is the size of the `CustomMultiChildLayout` itself.
Size leadingSize = Size.zero; // If there is no widget with id `1`, the size will remain at zero.
// Remember that `1` here can be any **id** - you specify them using LayoutId.
if (hasChild(1)) {
leadingSize = layoutChild(
1, // The id once again.
BoxConstraints.loose(size), // This just says that the child cannot be bigger than the whole layout.
);
// No need to position this child if we want to have it at Offset(0, 0).
}
if (hasChild(2)) {
final secondSize = layoutChild(
2,
BoxConstraints(
// This is exactly the same as above, but this can be anything you specify.
// BoxConstraints.loose is a shortcut to this.
maxWidth: size.width,
maxHeight: size.height,
),
);
positionChild(
2,
Offset(
leadingSize.width, // This will place child 2 to the right of child 1.
size.height / 2 - secondSize.height / 2, // Centers the second child vertically.
),
);
}
}
}
,但是如果您有特定的ID,则使用feature_discovery
注意事项
- 在此示例中,我使用
feature_discovery
和MultiChildLayoutDelegate
implementation作为id
MultiChildLayoutDelegate
可能是处理ID的最佳方法。CustomMultiChildLayout
in the build
method传递给CustomMultiChildLayout
(例如build
)。shouldRelayout
很好地解释了我在上面描述的内容,在这里您还将看到为什么我说performLayout
在理解getSize
的工作原理之后变得非常明显:当多个小部件的大小和位置之间存在复杂的关系时,
getSize
是适当的。要控制单个孩子的布局,CustomMultiChildLayout
更合适。这也意味着使用
class YourLayoutDelegate extends MultiChildLayoutDelegate { YourLayoutDelegate({this.position}); final Offset position; @override void performLayout(Size size) { // ... (layout code from above) } @override bool shouldRelayout(YourLayoutDelegate oldDelegate) { return oldDelegate.position != position; } }
遵循我上面描述的相同原理,但是没有ID,因为只有一个孩子。您需要使用CustomMultiChildLayout( delegate: YourLayoutDelegate(position: Offset.zero), children: [ // ... (your children wrapped in LayoutId's) ], )
代替,它具有用于实现布局的不同方法(它们均具有默认行为,因此从技术上讲,它们对于override
都是可选的):
1
,等效于我传递给以上2
的约束。enum
,相当于上面的Listenable
。其他所有内容都完全相同(请记住,您不需要super
,只有一个孩子而不是super(relayout: animation)
)。
CustomSingleChildLayout
CustomSingleChildLayout
的基础。使用此功能需要更深入的Flutter知识,并且再次复杂一些,但是如果您需要更多的自定义设置,则它是更好的选择,因为它甚至更低。与The documentation相比,这有一个major
优势(通常有更多控制权):CustomSingleChildLayout
无法调整大小
CustomMultiChildLayout
)。出于明显的原因,我不会在这里解释如何使用CustomMultiChildLayout,但是如果您有兴趣,您可以在2020年1月20日之后签出CustomSingleChildLayout,在此我会大量使用CustomSingleChildLayout
-我还将写一封关于此的文章,应该解释一下所有这些如何工作。[现在您可以记住SingleChildLayoutDelegate
是使SingleChildLayoutDelegate
成为可能的原因,直接使用它会为您带来一些好处,例如不必使用getConstraintsForChild
而可以访问getConstraintsForChild
的父数据直接。
有趣的事实