栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Flutter中使用CustomMultiChildLayout和CustomSingleChildLayout

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Flutter中使用CustomMultiChildLayout和CustomSingleChildLayout

首先,我想说的是,很高兴为您提供帮助,因为我可以理解您的工作-自己解决问题也有好处(文档很棒)。

CustomSingleChildLayout
在我
CustomMultiChildLayout
向您解释后,将会明白什么。

CustomMultiChildLayout

这个小部件的要点是允许您将传递给该小部件的子项 布置 在一个函数中,即,它们的位置和大小可以相互依赖,这是 无法
使用例如预制

Stack
小部件实现的。

CustomMultiChildLayout(  children: [    // Widgets you want to layout in a customized manner  ],)

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

  1. 您要传递给的每个孩子都
    children
    必须是a,
    LayoutId
    然后将您实际上想显示为孩子的小部件传递给该对象
    LayoutId
    。该
    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'),        ),      ],    )
  1. 您需要创建一个
    MultiChildLayoutDelegate
    处理布局部分的子类。这里的文档似乎非常复杂。
    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
    ,可让您检查是否将特定 ID (记住
    LayoutId
    ?)传递给
    children
    ,即是否存在该ID的子代。

  • layoutChild
    ,您需要为每个孩子的每个 id 调用一次,只需提供 一次即可 ,它将给您
    Size
    那个孩子的。

  • 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. ),          );        }      }    }

其他两个例子是从文档(检查准备一个 第2步 )和 真实世界
我写的一段时间例如背部

feature_discovery
包:
MultiChildLayoutDelegate
执行和
CustomMultiChildLayout
build
方法。

最后一步是重写

shouldRelayout
method,该方法
performLayout
通过与旧的委托进行比较(可选地也可以重写
getSize
)并将委托添加到您的方法中,简单地控制是否应在任何给定时间点再次调用
CustomMultiChildLayout

    class YourLayoutDelegate extends MultiChildLayoutDelegate {      YourLayoutDelegate({this.position});      final Offset position;      @override      void performLayout(Size size) {        // ... (layout pre from above)      }      @override      bool shouldRelayout(YourLayoutDelegate oldDelegate) {        return oldDelegate.position != position;      }    }    CustomMultiChildLayout(      delegate: YourLayoutDelegate(position: Offset.zero),      children: [        // ... (your children wrapped in LayoutId's)      ],    )

注意事项

  • 在此示例中,我使用

    1
    2
    作为 id ,但是
    enum
    如果您有特定的ID ,使用an 可能是处理ID的最佳方法。

  • 如果您想对布局过程进行动画处理或通常基于可听类触发它,则可以将传递

    Listenable
    super
    (例如
    super(relayout: animation)
    )。

CustomSingleChildLayout

该文档很好地解释了我上面所描述的内容,在这里您还将了解为什么我说了这

CustomSingleChildLayout
一点,但在理解其
CustomMultiChildLayout
工作原理之后将非常明显:

如果多个小部件的大小和位置之间存在复杂的关系,则CustomMultiChildLayout是合适的。要控制单个孩子的布局,CustomSingleChildLayout更合适。

这也意味着使用

CustomSingleChildLayout
遵循我上面描述的相同原理,但是没有ID,因为只有一个孩子。
您需要使用
SingleChildLayoutDelegate
相反的方法,该方法具有不同的方法来实现布局(它们都具有默认行为,因此从技术上讲,它们都是可选的,可以 覆盖 ):

  • getConstraintsForChild
    ,相当于我
    layoutChild
    上面传递的约束。

  • getPositionForChild
    ,相当于
    positionChild
    上述内容。

其他所有内容都完全相同(请记住,您不需要

LayoutId
,只有一个孩子而不是
children
)。


MultiChildRenderObjectWidget

这是

CustomMultiChildLayout
建立在上面的。
使用此功能需要更深入的Flutter知识,并且再次复杂一些,但是如果您需要更多的自定义设置,则它是更好的选择,因为它的级别更低。与(通常有更多控制权)相比,这具有一个
主要 优势
CustomMultiChildLayout

CustomMultiChildLayout
无法 根据其子项确定 自身 _ 大小_
(请参见有关更好的文档说明)。

MultiChildRenderObjectWidget
出于明显的原因,我不会在此说明如何使用。但是,如果您有兴趣,可以查看我在2020年1月20日之后提交给Flutter
Clock挑战赛的内容,我在其中
MultiChildRenderObjectWidget
广泛使用-
您还可以阅读有关此内容的文章,这应该解释所有工作原理。

现在您可以记住,这

MultiChildRenderObjectWidget
是有
CustomMultiChildLayout
可能的,直接使用它会为您带来一些好处,例如不必使用
LayoutId
,而是可以直接访问
RenderObject
的父数据。

有趣的事实

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



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/418497.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号