如何在绘制之前知道小部件的大小?

Posted

技术标签:

【中文标题】如何在绘制之前知道小部件的大小?【英文标题】:How to know the size of a widget before painting it? 【发布时间】:2019-10-13 07:52:00 【问题描述】:

我正在尝试使用AnimatedContainer 来实现用户按下时的展开效果的简单动画(类似于ExpandableTile)。

我的问题是这个容器在展开时可以有 10.0 的高度或 1000.0(它必须是动态的)。好的,要对其进行动画处理,它需要事先知道高度,这是有道理的。但是在渲染它之前我怎么知道它的最大高度(我要渲染可以有 1 到 N 行的文本)。

我想了很多可能性,但似乎没有一个适合。大多数时候,我们从已经渲染的东西中获取大小,从RenderBox,而不是相反,所以这让我很烦。

提前谢谢你!

【问题讨论】:

制作自己的渲染框 对于看起来如此常见的用例是否有必要?创建我自己的 RenderBox 对我有什么帮助?你能提供一个简单的例子吗?泰雷米。 这种情况并不常见。大多数现有技术不提供此类功能。问题是它需要对该元素进行两次布局。太贵了 您知道实现此类功能的其他好方法吗?即使走昂贵的路,您认为哪种方式最好? 【参考方案1】:

我最终通过使用非常适合这种情况的Offstage 小部件找到了解决方案。

解决方案

将子树包装在Offstage 中并为其分配一个键(可以是GlobalKey),然后,在实际渲染它之前,我可以通过以下操作获得它的高度:

  void _getWidgetHeight() 
    if (subtreeHeight == null) 
      RenderBox renderBox = key.currentContext.findRenderObject();
      subtreeHeight = renderBox.size.height;
    
    setState(() 
      _isOffstage = false;
    );
  

这样,如果你有一个AnimatedContainer,例如,并且需要动画到它的最终大小,你可以有以下:

AnimatedContainer(
        duration: Duration(milliseconds: 250),
        height: subtreeHeight ?? 100.0 // some default size,
      ...
  )

它会相应地渲染。

请注意,确保子树中的内容可以插入到 Container 中,而它正在制作动画(例如,如果您在 Column 中使用它,则将 Offstage 包装在 Flexible 中或Row)。

【讨论】:

您有其他解决方案吗? 没有,AFAIK。在访问其大小之前,您需要始终绘制小部件。 Offstage 通过在树中插入小部件而不实际显示它来实现它。 请看***.com/q/67056614/6447123,我们有TextPainter.size的文本,基本上小部件必须有类似的类 @MiguelRuivo 你好..你能分享一个最低工作代码吗?谢谢..我面临着类似的情况

以上是关于如何在绘制之前知道小部件的大小?的主要内容,如果未能解决你的问题,请参考以下文章

隐藏子小部件时,QGridLayout 未调整大小或重新绘制

更改新小部件的大小

如何在 tkinter 中找出当前小部件的大小?

Qt 如何从 QVector 中的数据创建位图并将其显示在小部件上?

如何在tkinter中找出当前的小部件大小?

如何在 GTK 中更新(绘制)一个小部件和仅这个小部件