什么是CustomMultiChildLayout和CustomSingleChildLayout?

问题描述 投票:1回答:1

具有使用CustomSingleChildLayoutCustomSingleChildLayout类的经验的人能够(通过示例)详细解释如何使用它们。

我是Flutter的新手,正在尝试了解如何使用它们。但是,该文档太糟糕了,不清楚。我试图在Internet上搜索示例,但没有其他文档。

如果您能提供帮助,我将永远感激。

谢谢!

flutter dart flutter-layout
1个回答
1
投票

首先,我很高兴能为您提供帮助,因为我可以理解您的奋斗-自己弄清楚它有很多好处(特别是因为Flutter文档实际上非常惊人,与它相反可能看起来很沮丧。

CustomMultiChildLayout的作用在我向您解释CustomMultiChildLayout之后将显而易见。

CustomSingleChildLayout

此小部件的要点是允许您通过单个功能layout传递给此小部件的子代,即,它们的位置和大小可以相互依赖,这是您无法实现的事情例如预建的CustomMultiChildLayout小部件。

CustomMultiChildLayout

现在,您需要执行另外两个步骤,然后才能开始布置孩子:

  1. 传递给CustomMultiChildLayout的每个孩子都必须是Stack,然后将实际上要显示为孩子的小部件传递给CustomMultiChildLayout( children: [ // Widgets you want to layout in a customized manner ], ) children将唯一地标识您的窗口小部件,使它们在布局时可访问:
LayoutId
  1. 您需要创建一个处理布局部分的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
例子:layoutChildSize最后一步是覆盖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. ), ); } } }

feature_discovery
注意事项

,但是如果您有特定的ID,则使用MultiChildLayoutDelegate可能是处理ID的最佳方法。
  • 如果您想为布局过程设置动画或通常基于可听的方式触发它,可以将CustomMultiChildLayout in the build method传递给CustomMultiChildLayout(例如build)。
  • shouldRelayout method

    [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的父数据直接。

    有趣的事实

    我以纯文本格式(在StackOverflow文本字段中)编写了所有代码,因此,如果有错误,请向我指出,然后我将对其进行修复。

    © www.soinside.com 2019 - 2024. All rights reserved.