加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

了解颤振渲染引擎

发布时间:2020-12-14 14:52:50 所属栏目:百科 来源:网络整理
导读:关于如何更新ListView的文档 here说: In Flutter,if you were to update the list of widgets inside a setState(),you would quickly see that your data did not change visually. This is because when setState() is called,the Flutter rendering engi
关于如何更新ListView的文档 here说:

In Flutter,if you were to update the list of widgets inside a
setState(),you would quickly see that your data did not change
visually. This is because when setState() is called,the Flutter
rendering engine looks at the widget tree to see if anything has
changed. When it gets to your ListView,it performs a == check,and
determines that the two ListViews are the same. Nothing has changed,
so no update is required.

For a simple way to update your ListView,create a new List inside of
setState(),and copy the data from the old list to the new list.

我不知道渲染引擎如何确定在这种情况下Widget Tree中是否有任何更改.

AFAICS,我们关心调用setState,它将State对象标记为脏并要求它重建.重建后会有一个新的ListView,不是吗?那么为什么==检查说它是同一个对象呢?

此外,新的List将是State对象的内部,Flutter引擎是否比较State对象内的所有对象?我认为它只比较了Widget树.

所以,基本上我不明白渲染引擎如何决定它将要更新什么以及将要忽略什么,因为我无法看到创建新List如何将任何信息发送到渲染引擎,因为文档说渲染引擎只是寻找一个新的ListView …而AFAIK新的List不会创建一个新的ListView.

解决方法

颤振不仅仅是 Widgets.

调用setState时,将Widget标记为脏.但是这个Widget实际上并不是你在屏幕上呈现的内容.
存在创建/变异RenderObjects的小部件;这些RenderObjects在屏幕上绘制您的内容.

RenderObjects和Widgets之间的链接使用一种新的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重绘,必须在所需的renderObject上调用markNeedsPaint或markNeedsLayout.

这通常由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;
  }
}

但它暗示如果您改变列表而不是创建新列表,则RenderObject将不会被标记为需要重新布局/重绘.因此,不会有任何视觉更新.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读