【问题标题】:How to use the constraints and sizes of other widgets during the build phase如何在构建阶段使用其他小部件的约束和大小
【发布时间】:2018-11-19 15:19:56
【问题描述】:

我想确保我涵盖所有情况

  1. 父窗口小部件读取(并可能使用)孩子的大小或约束

  2. 子部件读取(并可能使用)父部件的大小或约束

  3. 子部件读取(并可能使用)另一个子部件的大小或约束

解决方案似乎是……

  1. 让构建阶段运行

  2. 然后构建我要从中检索数据的小部件的大小和约束

  3. 然后我中断了常规的阶段序列(因此draw Frame函数不运行)

  4. 然后使用我现在拥有的数据重新运行构建阶段

  5. 并允许框架绘制

问题是我不知道该怎么做

我早些时候发布了一个与此相关的更具体的问题,我得到了一些回复,布局构建器、自定义多子布局和自定义单子布局...

但这些都是针对特定情况的

布局构建器构建一个小部件树,该树可以依赖于父小部件的大小。所以它只处理案例2

另外两个有限制,父母的大小不能取决于孩子的大小。所以它似乎暗示它只处理案例 2。

那么还有哪些其他解决方案呢?

rect getter 插件可以工作,但不会中断绘图帧,因此会出现一帧卡顿 https://pub.dartlang.org/packages/rect_getter

我还没有尝试过后布局插件,但似乎发生了同样的问题,因为它说它在第一帧之后运行 https://pub.dartlang.org/packages/after_layout

感谢任何帮助! 我不想忍受不断地使用变通方法:/

【问题讨论】:

  • rect_getterafter_layout 听起来都像是不需要的插件。他们带来的东西都是开箱即用的衬垫
  • 是的,您不需要它们,但它们很容易参考(就像我在这里所做的那样)
  • 您的用例看起来很奇怪,并且很容易在布局中出现“死锁”...您能否提供一个具体、详细的示例来说明您要实现的目标?

标签: flutter flutter-layout


【解决方案1】:

小部件不能故意做这样的事情。 一个小部件应该从不依赖于大小和位置或任何东西。甚至他们的孩子也不行。

如果您遇到需要的情况,LayoutBuilder 大部分时间应该没问题。

如果不是,您要创建的不是Widget。但是一个RenderObject 反而是flutter的下层之一。

诸如CenterStackColumn 之类的小部件实际上是使用RenderObject 计算的。

【讨论】:

  • 布局构建器仍然有限制,因此它不能涵盖所有情况。但是是的,我知道如何访问渲染对象(这就是 rect getter 所做的),但我不知道如何阻止布局阶段触发下一个阶段,然后在最后一个阶段触发 draw Frame 函数。所以我想访问该渲染对象数据,但我想这样做并停止框架运行......所以本质上对于那个框架来说,这就是阶段应该如何进行......构建布局构建布局......绘制框架。 .. 重复构建和布局过程,直到您获取所需的所有数据
  • 我不是说访问渲染对象。我的意思是编写 RenderObject 的子类并在小部件上使用它。
  • 也许是我对系统不熟悉...但我不明白这有什么帮助...我需要获取渲染对象信息(在渲染树中可见)但那是在构建阶段计算
  • 小部件根本不调整大小或定位任何东西。渲染对象可以。它是包含所有布局逻辑的 RenderObjects。小部件只是在这里通过限制某些用法(例如取决于您的父/子大小)来简化 RenderObjects 的使用。但是 RenderObjects 本身没有这样的限制
  • 只需打开StackAlign的代码即可。您会看到,实际上除了实例化 RenderStackRenderAlign 之外,它们几乎什么都不做。
【解决方案2】:

我是 rect getter plugin 的作者,我对你的问题很感兴趣。

是的,正如其他人所说,我认为 Flutter 是一个非常灵活的 UI 框架,所以在大多数情况下我们不需要知道小部件的实际大小。但是当我尝试写一个动画效果并模拟打开一本书时,我发现有必要知道一个'Card'的rect信息,最后我找到了从源代码中从一个撕裂的对象中获取一个rect的方法heros.dart。结果,它变成了你所知道的 rect getter 插件。

其实我可能也遇到了和你一样的问题,因为我想写一个像this这样的'Masonry'布局,所以我应该知道之前item的rect信息来决定当前item应该画在哪里.

我的解决方案是: 1.通过rect_getter包裹子widget,先正常构建布局; 2.然后,构建完成后立即使用定时器获取孩子的rect信息; 3.调用setState()重建布局,利用children的rect信息计算每个child在viewport中的constraintbox。

代码片段(未完成):

及目前进展:

我的代码可以找到here,但是它们太糟糕了,并且评论使用中文,所以我认为您不会想阅读它们。

【讨论】:

  • 是的@debuggerx 这正是我正在做的,但我得到了每个依赖项的“口吃”框架......这是因为在每个构建阶段之后,阶段的自然进展继续并绘制视觉框架...然后调用设置状态并再次运行构建...这整个过程发生在每个依赖项上...所以假设您有A依赖于B,这取决于C,这取决于D...您会有3个“口吃帧”......所以我想做的是找到一种方法来避免这种情况......有什么想法吗?!
猜你喜欢
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多