Flutter不仅由Widget组成。
调用时
setState,将 Widget 标记为脏。但是,此小部件实际上并不是您在屏幕上渲染的。存在用于创建/
更改RenderObject的小部件;这些RenderObjects在屏幕上绘制内容。
RenderObject和Widget之间的链接是使用一种新型的Widget完成的:RenderObjectWidget(例如LeafRenderObjectWidget)
Flutter提供的大多数小部件在某种程度上都是RenderObjectWidget,包括ListView。
一个典型的RenderObjectWidget示例是这样的:
class MyWidget extends LeafRenderObjectWidget { final String title; MyWidget(this.title); @override MyRenderObject createRenderObject(BuildContext context) { return new MyRenderObject() ..title = title; } @override void updateRenderObject(BuildContext context, MyRenderObject renderObject) { renderObject ..title = title; }}本示例使用小部件创建/更新RenderObject。仅仅通知框架还有一些东西需要重画。
要进行RenderObject重绘,必须调用
markNeedsPaint或
markNeedsLayout在所需的renderObject上进行。
通常这是由RenderObject本身使用自定义字段设置器通过以下方式完成的:
class MyRenderObject extends RenderBox { String _title; String get title => _title; set title(String value) { if (value != _title) { markNeedsLayout(); _title = value; } }}请注意
if (value != previous)。
此检查可确保在不更改任何内容的情况下重建窗口小部件时,Flutter不会重新布局/重新绘制任何内容。
正是由于这种确切的条件,突变
List或
Map没有重新
ListView渲染。它基本上具有以下内容:
List<Widget> _children;List<Widget> get children => _children;set children(List<Widget> value) { if (value != _children) { markNeedsLayout(); _children = value; }}但它意味着,如果 发生变异 的名单,而不是创建一个新的,在渲染对象不会被标记为需要重新布局/重绘。因此,将不会有任何视觉更新。



