精华内容
下载资源
问答
  • 今天是第一个 Flutter iOS App 上架,激动,还有点担心。问题还不少,总结一下,让大家少入坑。 问题集锦 问题一: ERROR ITMS-90189: Redundant Binary Upload. You've already uploaded a build with build number...
  • 整理了,Flutter优缺点、Flutter原理、Flutter框架结构等等内容,内容来自于各个大神的博客,本人只是个搬运工。
  • Flutter 是 Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用。开发者可以通过 Dart语言开发 App,一套代码可同时运行在 iOS 、Android、Mac、Windows等平台,甚至能生成Web版,运行于...
  • Flutter 框架层次结构

    千次阅读 2020-07-23 08:37:56
    Flutter 是一个非常优秀的跨平台开发框架,基于 Flutter 我们可以用很少的代码快速的开发出界面精美的 APP ,同时热重载机制也极大的提高了我们的开发效率,并且基于 Flutter开发的 APP 运行起来也是如.

    作者:Frederik Schweiger

    链接:

    https://medium.com/flutter-community/the-layer-cake-widgets-elements-renderobjects-7644c3142401

    说明:声明原创才能给文章加标签

     

    Flutter 是一个非常优秀的跨平台开发框架,基于 Flutter 我们可以用很少的代码快速的开发出界面精美的 APP ,同时热重载机制也极大的提高了我们的开发效率,并且基于 Flutter开发的 APP 运行起来也是如丝般顺滑,能够达到 120 fps。

     

    那么,你对此有没有过疑问,Flutter 是怎么这么快的?这里面有什么奥秘吗?或者,更直接一点,Flutter 到底是怎么工作的?接下来的内容希望能够给你答案。

     

    你肯定早就听说过了,Flutter 中万物皆是 Widget,你的 app 是一个 widget,text 是一个widget,一个 widget 外面包裹的 padding 也是一个 widget ,甚至手势识别的功能也是通过 widget 来实现的。当然,这不是全部的真相,如果我告诉你,确实我们通过使用 widget 让我们的开发变得简单高效,但是我们能够创建一个 Flutter app 不适用哪怕是一个 widget 呢?接下来,就让我稍微深入的探索一下这个框架吧。

     

    01

    框架入门

     

    也许你已经在一些类似于‘Flutter入门介绍’的文章中对Flutter有了比较大致的了解,但是你可能没有准备好去理解这些层次结构背后的那些概念和原理,也行你也曾和我一样,呆呆的看着这张图片却得不到任何东西,别担心,我会帮助你的,我们还是先来看一下这个图片吧。

     

     

    Flutter 框架由许多抽象的层级组成,在这些层级的最顶端是我们经常用到的Material和Cupertino Widget,这下面是封装更通用组件的 Widget 层。通常情况下,你会发现你仅仅使用这两层中的 Widget 就够用了,并且目前你所能看到或者使用的,也基本都来着这两层,比如页面脚手架组件 Scaffold 和 FlaotingActionButton 来自 Meterial 包,Column 和 GestureDector 来自 widgets 层。 

     

    在Widget层下面是 Rendering 层。Rendering层简化了布局和绘制过程。它是 dart:ui 层的抽象化。dart:ui是框架的最底层,它负责处理与 Flutter Engine 的通信。

     

    简而言之,层级越高,封装度越高,我们使用越方便,然后层级越低使用起来可能更加自由,控制粒度更精细,当然也会更加复杂。

     

    dart:ui 层

    dart:ui library 暴露了最底层的服务,Flutter 框架基于这一层来构建应用程序,比如输入驱动、,绘制文字,布局和渲染系统等。

    所以你可以仅仅通过使用  dart:ui库中的类(例如CanvasPaintTextField)来构建一个Flutter App。但是如果你对于直接在canvas上绘制比较熟悉,你就知道了绘制不仅仅是绘制一个简笔画图像,首先绘制管理就让人头疼,同时还要考虑管理和组织如何布局,并且当你触摸了你 app 上的元素,你还要能够计算出来并响应(hit-testing)。

     

    那这究竟意味着什么呢?意味着你必须要精确的计算出你布局中所有元素的坐标,然后还要实现绘制到屏幕的功能,同时能够对外界的输入事件(触摸屏幕)能够捕获到做出响应。对于屏幕上绘制的每一帧,你都要实现这些功能,通过这种方式来开发的 APP,如果只是在一个蓝色区块上显示一个文本这种简单的界面应用,可能还能实现,但是如果是一个购物应用程序或者一个游戏,这可能就是不可能实现的了,更不要说自己去处理动画和实现复杂精美的界面效果了。我只是把我的经验告诉你,如果用这种方式开发这将是我们开发者的噩梦。

     

     Rendering 层

    Rendering 层,也就是 Flutter 的渲染树(Flutter rendering) 。Widgets 层 使用 RenderObject 来实现了布局和绘制。通常情况下,如果你是使用自定义 RenderBox 来实现一些特殊效果,用到的就是这一层提供的类,但是大多数情况下,我们和这层的交互都是当我们遇到了一个布局问题而 debug 时。

    Rendering 层是 dart:ui 层上的第一个抽象层,同时这层替我们做了全部发的复杂的数

    学计算工作(比如持续追踪计算元素的坐标值),Rendering 层是通过 RenderObjects 来完成工作的。你可以把 RenderObjects 想象成汽车的发动机,我们的 app 能够真的的显示到屏幕上就是通过RenderObjects 来完成的,由 RenderObjects 所组成的渲染树会被 Flutter 分层布局并渲染到屏幕上。当然为了优化这些复杂的流程,Flutter 也使用了一些智能算法,会缓存每次的计算结果,每次都只更新很小的部分。

     

    通常情况下,Flutter 使用 RenderBox 而不是 RenderObject,这是因为 Flutter 开发者发现,简单的盒约束布局模型也能够很好的完成工作构建精美的界面,想象一下,每个 widget 都有自己盒子约束模型,在一个盒子当中,计算了其约束关系和大小等,然后把这个 widget 加入到一个已经计算好盒子系统当中,这里面,如果有一个 widget 发生了改变,系统只需要重新计算这个 widget 所在盒子的约束关系即可。

     

    Widgets 层

    Flutter Widgets 框架层

    Widgets 这层是很有意思的一层,这层给我们提供了可以直接使用的 UI 组件,这里面所有的组件都可以分成三类,每一类都有对应的 RenderObject 来处理。

     

    布局相关(layout)

    比如 Column 和 Row ,这两个 Widget 可以帮我们轻松的实现水平或者垂直排列组件。

     

    绘制相关(Parning)

    比如 Text 和 Image ,这类的组件可以帮我们展示或者说渲染一些内容到屏幕上。

     

    手势检测相关

    比如 GestureDetector 组件,这个组件能够检测到屏幕点击或者滑动事件。

     

    通常来说,我们都是通过使用这些基础组件来组成我们自己的组件或者组件树,比如我们可以使用 GestureDetector 包裹 Container 来监听点击事件从而实现一个按钮组件。

     

     Material & Cupertino 层

    这层的 Widget 是 Widgets 层的封装,只不过是实现了 Material 和 Cupetino 风格的 Widget 提供给我们使用。

    总的来说,Flutter 框架的设计思想就是抽象和封装,这可以让我们开发者开发更加方便。这层是 Flutter 框架的第四层,这里面的组件都是 Flutter 框架封装好的提供给我们使用,Material 是材料设计风格的而 Cupetino 是 iOS 风格的,比如 AlertDialog、Switch 和 FloatingActionButton ,如果你是 iOS 开发者,那么你可以使用 CupertinoAlertDialog 、CupertinoButton 和 CupertinoSwitch ,这些组件你可能看起来更熟悉。

     

    Flutter为了减少开发者的负担,创建了这个拥有Material和Cupertino风格的Widgets层。

     

     

    02

    综合分析

     

    思考一下,RenderObject 是如何与 Widgets 联系起来的呢?Flutter是如何创建布局的?Element又是什么呢?上面已经对框架结构进行了简单的介绍,接下来看一下真的的实践,比如下面简单的 控件树。

    ps: 我们实际开发中使用的 widget,比如 Text,都是由许多其他的 Widget 来组成的,为了演示和讲解,这里用抽象的 Widget (SimpleContainer 和 SimpleText) 来代替 。

    我们构建的这个 APP 是非常简单的。它由三个Stateless Widget组成:SimpleApp、SimpleContainer、SimpleText。当我们调用 Flutter 的 runApp() 方法会发生什么呢?

     

    当 Flutter 运行 runApp() 之后,这背后将会运行下面一些列事情:

    1、Flutter 将会构建包含这三个 Widget 的 Widgets 树。

    2、Flutter 遍历 Widget 树,通过 Widget 里面的 createElement 方法来创建其关联的 Element 对象,然后将这些对象组建成 Element 树。

    3、最后 ,Element 会调用 createRenderObject() 方法来创建想关联的 RenderObject 对象,并组建第三棵树,RenderObject 树。

     

    当 Flutter 创建好了三个对应的树之后,可以用如下图片来描述:

    此时,Flutter 创建了三个不同的树,一个是 Widget 树、一个是 Element 树,一个是 RenderObject 树,并且,每个 Element 都会持有对应的 Widget 和 RenderObject 的引用。

     

    接下来看一下什么是 RenderObject 。

    RenderObject 里面实现了渲染其对应的 widget 的所有逻辑,同时 RenderObject 对象的实例化是一个非常重量级的操作,不仅如此,这里面还要实现布局、渲染以及手势检测。因此,一个 RenderObject 对象的实例应该尽可能的缓存到内存中,直到不用之后再回收它们。

     

    接下来就该说到 Element 了,Element 其实就像是 RenderObject 和 Widget 之间的粘合剂,Widtet 是不可变的,而 RenderObejct 是可变的。Element 可以看作是一个 Widget 在 Widget 树中特定位置的一个实例,Element 也同时持有其关联的 Widget 和 RenderObject 的引用。

     

    为什么使用三个树而不是一个树呢?

    简而言之是为了性能。当 Widget 树改变的时候,Flutter使用 Element 树来比较新的 Widget 树和已经创建的 RenderObject 树。当一个 Widget 的类型和上一次的 Widget 类型相同,那么 Flutter 就不会重新创建 RenderObject 了(太耗性能),只要更新一下其变化的参数配置就行了。由于 Flutter 中 widget 的创建和销毁都是轻量级的操作,因此用 widget 来做做为配置参数来描述当前 app 的状态再好不过了。而 RenderObject 的创建是一个重量级的操作,因此 RenderObejct 要尽可能的复用。

     

    然而,在Flutter 框架中,Element是被抽离开来的,所以我们不需要经常和它们打交道。每个Widget的 build(BuildContext context)方法中传递的 context 就是实现了BuildContext 接口的 Element,这也就是为什么相同类别的单个Widget 会不同的原因。

     

    03

    深入分析

     

    因为 Widget 是不可变的,当某个 Widget 的配置改变的时候,整个 Widget 树都需要被重建。例如当我们把我们上面代码里面的 Container 的颜色为红色的时候,Flutter 框架就会触发重建整个 Widget 树的操作。然后在 Element 的帮助下,Flutter 会比较新的 Widget 树中的第一个 Widget 和 RenderObject 树中第一个 RenderObject 。接下来比较Widget树中第二个 Widget 和RenderObject 树中第二个 RenderObject,以此类推,直到 Widget 树和 RendObject 树比较完成。

    Flutter 会遵循一个最基本的原则:判断新创建的 Widget 和老的 Widget 是否是同一个类型。如果不是同一个类型,那就把 Widget、Element、RenderObject 分别从它们的树(包括它们的子树)上移除,然后创建新的对象。如果是一个类型,那就仅仅修改 RenderObject中的配置,然后接着遍历其他对象。

     

    在我们的例子中,SimpleApp Widget 是和原来一样的类型,它的配置也是和原来的 SimpleAppRender 一样,所以什么都不会发生。下一个 item 在 Widget 树中是 SimpleContainer Widget,它的类型和原来是一样的,但是它的颜色变化了,RenderObject的配置发生变化了。因为SimContainer 仍然需要一个SimpleContainerRender 来渲染,因此 Flutter 只是更新了SimpleContainerRender的颜色属性,然后要求它重新渲染。其他的对象保持不变。

     

    当 widget 树重新创建之后的状态如下图所示(需要注意的是,Element 和 RenderObject 依然是同一个实例对象)

    这个过程是非常快的,因为Flutter 非常擅长创建那些轻量级的 Widgets。那些重量级的 RenderObject 则是保持不变,直到与其相对应类型的 Widget 从 Widget 树中被移除。那如果Widget的类型发生改变了会发生什么?

     

    比如将 SimpleText 替换为 SimpleButton

    和上面一样,Flutter 会重建 Widget 树,并遍历这棵树,然后比较 Widget 的类型是否和 RenderObject 中的对象对应。

     

    此时三颗树的状态如下所示,改变类型的 Widget 对应的 Element 和 SimpleTextRender 已经被移除了

    因为SimpleButton 的类型与 Element 树中相对应位置的 Element 的类型不同,Flutter将会从另外两棵树上删除对应的 Element 和相对应的 SimpleTextRender。然后Flutter 将会重建与 SimpleButton 相对应的 Element 和 RenderObject 对象实例。

     

    最终的状态如下

    然后新的 RenderObject 树已经被重建,然后重新布局并绘制在屏幕上面。在这里面,Flutter 做了大量优化工作并且其使用的缓存策略,能够让我们不必手动的对这些对象进行管理。

     

    04

    总结

     

    现在你应该对 Flutter 是如何工作的,为什么能够渲染复杂的布局并且运行的还很流畅有了一定的了解,这里面还没有讲到 State,Flutter 引入了 State 来提升了这个过程的整体性能,今天暂时不对此进行讨论了,希望这篇文章能够帮助你理解 Flutter 框架。

     

     

    推荐阅读

    Widget、RenderObject 与 Element

    深入理解 Flutter 多线程

    Flutter 内部工作原理

    展开全文
  • Flutter 是一个非常优秀的跨平台开发框架,基于 Flutter 我们可以用很少的代码快速的开发出界面精美的 APP ,同时热重载机制也极大的提高了我们的开发效率,并且基于 Flutter 开发的 APP 运行起来也是如丝般顺滑,...

    作者: Frederik Schweiger
    链接 : The Layer Cake

    Flutter 是一个非常优秀的跨平台开发框架,基于 Flutter 我们可以用很少的代码快速的开发出界面精美的 APP ,同时热重载机制也极大的提高了我们的开发效率,并且基于 Flutter 开发的 APP 运行起来也是如丝般顺滑,能够达到 120 fps。那么,你对此有没有过疑问,Flutter 是怎么这么快的?这里面有什么奥秘吗?或者,更直接一点,Flutter 到底是怎么工作的?接下来的内容希望能够给你答案。

    你肯定早就听说过了,Flutter 中万物皆是 Widget,你的 app 是一个 widget,text 是一个widget,一个 widget 外面包裹的 padding 也是一个 widget ,甚至手势识别的功能也是通过 widget 来实现的。当然,这不是全部的真相,如果我告诉你,确实通过使用 widget 让我们的开发变得简单高效,但是我们能够创建一个 Flutter app 不使用哪怕是一个 widget 呢?接下来,就让我稍微深入的探索一下这个框架吧。

    一、框架入门

    也许你已经在一些类似于‘Flutter入门介绍’的文章中对Flutter有了大致的了解,但是你可能还没有准备好去理解这些层次结构背后的那些概念和原理,也许你也曾和我一样,呆呆的看着这张图片却得不到任何东西,不用担心,我会帮助你来理解,我们还是先来看一下这个图片吧。

     

     

     

    Flutter 框架由许多抽象的层级组成,在这些层级的最顶端是我们经常用到的 Material 和 Cupertino Widget,这下面是封装更通用组件的 Widget 层。通常情况下,你会发现你仅仅使用这两层中的 Widget 就够用了,并且目前你所能看到或者使用的,也基本都来自这两层,比如页面脚手架组件 Scaffold 和 FlaotingActionButton 来自 Meterial 包,Column 和 GestureDector 来自 widgets 层。

    在Widget层下面是 Rendering 层。Rendering层简化了布局和绘制过程。它是 dart:ui 层的抽象化。dart:ui是框架的最底层,它负责处理与 Flutter Engine 的通信。

    简而言之,层级越高,封装度越高,我们使用越方便,然后层级越低使用起来可能更加自由,控制粒度更精细,当然也会更加复杂。

    1、dart:ui 层

    dart:ui library 暴露了最底层的服务,Flutter 框架基于这一层来构建应用程序,比如输入驱动、,绘制文字,布局和渲染系统等。

    所以你可以仅仅通过使用 dart:ui库中的类(例如Canvas、Paint和TextField)来构建一个Flutter App。但是如果你对于直接在 canvas 上绘制比较熟悉,你就知道了绘制不仅仅是绘制一个简笔画图像,首先绘制管理就让人头疼,同时还要考虑管理和组织如何布局,并且当你触摸了你 app 上的元素,你还要能够计算出来并响应(hit-testing)。

    那这究竟意味着什么呢?意味着你必须要精确的计算出你布局中所有元素的坐标,然后还要实现绘制到屏幕的功能,同时能够对外界的输入事件(触摸屏幕)能够捕获到做出响应。对于屏幕上绘制的每一帧,你都要实现这些功能,通过这种方式来开发的 APP,如果只是在一个蓝色区块上显示一个文本这种简单的界面应用,可能还能实现,但是如果是一个购物应用程序或者一个游戏,这可能就是不可能实现的了,更不要说自己去处理动画和实现复杂精美的界面效果了。我只是把我的经验告诉你,如果用这种方式开发这将是我们开发者的噩梦。

    2、 Rendering 层

    Rendering 层,也就是 Flutter 的渲染树(Flutter rendering) 。Widgets 层 使用 RenderObject 来实现了布局和绘制。通常情况下,如果你是使用自定义 RenderBox 来实现一些特殊效果,用到的就是这一层提供的类,但是大多数情况下,我们和这层的交互都是当我们遇到了一个布局问题而 debug 时。

    Rendering 层是 dart:ui 层上的第一个抽象层,同时这层替我们做了全部发的复杂的数学计算工作(比如持续追踪计算元素的坐标值),Rendering 层是通过 RenderObjects 来完成工作的。你可以把 RenderObjects 想象成汽车的发动机,我们的 app 能够真的的显示到屏幕上就是通过RenderObjects 来完成的,由 RenderObjects 所组成的渲染树会被 Flutter 分层布局并渲染到屏幕上。当然为了优化这些复杂的流程,Flutter 也使用了一些智能算法,会缓存每次的计算结果,每次都只更新很小的部分。

    通常情况下,Flutter 使用 RenderBox 而不是 RenderObject,这是因为 Flutter 开发者发现,简单的盒约束布局模型也能够很好的完成工作构建精美的界面,想象一下,每个 widget 都有自己盒子约束模型,在一个盒子当中,计算了其约束关系和大小等,然后把这个 widget 加入到一个已经计算好盒子系统当中,这里面,如果有一个 widget 发生了改变,系统只需要重新计算这个 widget 所在盒子的约束关系即可。

    3、 Widgets 层

    Flutter Widgets 框架层

    Widgets 这层是很有意思的一层,这层给我们提供了可以直接使用的 UI 组件,这里面所有的组件都可以分成三类,每一类都有对应的 RenderObject 来处理。

    • 布局相关(layout)

    比如 Column 和 Row ,这两个 Widget 可以帮我们轻松的实现水平或者垂直排列组件。

    • 绘制相关(Parning)

    比如 Text 和 Image ,这类的组件可以帮我们展示或者说渲染一些内容到屏幕上。

    • 手势检测相关 比如 GestureDetector 组件,这个组件能够检测到屏幕点击或者滑动事件。

    通常来说,我们都是通过使用这些基础组件来组成我们自己的组件或者组件树,比如我们可以使用 GestureDetector 包裹 Container 来监听点击事件从而实现一个按钮组件。

    4、 Material & Cupertino 层

    这层的 Widget 是 Widgets 层的封装,只不过是实现了 Material 和 Cupetino 风格的 Widget 提供给我们使用。

    总的来说,Flutter 框架的设计思想就是抽象和封装,这可以让我们开发者开发更加方便。这层是 Flutter 框架的第四层,这里面的组件都是 Flutter 框架封装好的提供给我们使用,Material 是材料设计风格的而 Cupetino 是 iOS 风格的,比如 AlertDialog、Switch 和 FloatingActionButton ,如果你是 iOS 开发者,那么你可以使用 CupertinoAlertDialog 、CupertinoButton 和 CupertinoSwitch ,这些组件你可能看起来更熟悉。

    Flutter为了减少开发者的负担,创建了这个拥有Material和Cupertino风格的Widgets层。

    二、综合分析

    思考一下,RenderObject 是如何与 Widgets 联系起来的呢? Flutter是如何创建布局的?Element又是什么呢?

    上面已经对框架结构进行了简单的介绍,接下来看一下真的的实践,比如下面简单的 控件树。

     

     

     

    ps: 我们实际开发中使用的 widget,比如 Text,都是由许多其他的 Widget 来组成的,为了演示和讲解,这里用抽象的 Widget (SimpleContainer 和 SimpleText) 来代替 。

    我们构建的这个 APP 是非常简单的。它由三个Stateless Widget组成:SimpleApp、SimpleContainer、SimpleText。当我们调用 Flutter 的 runApp() 方法会发生什么呢?

    当 Flutter 运行 runApp() 之后,这背后将会运行下面一些列事情:

    1、Flutter 将会构建包含这三个 Widget 的 Widgets 树。

    2、Flutter 遍历 Widget 树,通过 Widget 里面的 createElement 方法来创建其关联的 Element 对象,然后将这些对象组建成 Element 树。

    3、最后 ,Element 会调用 createRenderObject() 方法来创建想关联的 RenderObject 对象,并组建第三棵树,RenderObject 树。

    当 Flutter 创建好了三个对应的树之后,可以用如下图片来描述:

     

     

     

    此时,Flutter 创建了三个不同的树,一个是 Widget 树、一个是 Element 树,一个是 RenderObject 树,并且,每个 Element 都会持有对应的 Widget 和 RenderObject 的引用。

    接下来看一下什么是 RenderObject 。

    RenderObject 里面实现了渲染其对应的 widget 的所有逻辑,同时 RenderObject 对象的实例化是一个非常重量级的操作,不仅如此,这里面还要实现布局、渲染以及手势检测。因此,一个 RenderObject 对象的实例应该尽可能的缓存到内存中,直到不用之后再回收它们。

    接下来就该说到 Element 了,Element 其实就像是 RenderObject 和 Widget 之间的粘合剂,Widtet 是不可变的,而 RenderObejct 是可变的。Element 可以看作是一个 Widget 在 Widget 树中特定位置的一个实例,Element 也同时持有其关联的 Widget 和 RenderObject 的引用。

    为什么使用三个树而不是一个树呢?简而言之是为了性能。当 Widget 树改变的时候,Flutter使用 Element 树来比较新的 Widget 树和已经创建的 RenderObject 树。当一个 Widget 的类型和上一次的 Widget 类型相同,那么 Flutter 就不会重新创建 RenderObject 了(太耗性能),只要更新一下其变化的参数配置就行了。由于 Flutter 中 widget 的创建和销毁都是轻量级的操作,因此用 widget 来做做为配置参数来描述当前 app 的状态再好不过了。而 RenderObject 的创建是一个重量级的操作,因此 RenderObejct 要尽可能的复用。

    然而,在Flutter 框架中,Element是被抽离开来的,所以我们不需要经常和它们打交道。每个Widget的 build(BuildContext context)方法中传递的 context 就是实现了BuildContext 接口的 Element,这也就是为什么相同类别的单个Widget 会不同的原因。

    三、深入分析

    因为 Widget 是不可变的,当某个 Widget 的配置改变的时候,整个 Widget 树都需要被重建。例如当我们把我们上面代码里面的 Container 的颜色为红色的时候,Flutter 框架就会触发重建整个 Widget 树的操作。然后在 Element 的帮助下,Flutter 会比较新的 Widget 树中的第一个 Widget 和 RenderObject 树中第一个 RenderObject 。接下来比较Widget树中第二个 Widget 和RenderObject 树中第二个 RenderObject,以此类推,直到 Widget 树和 RendObject 树比较完成。

     

     

     

    Flutter 会遵循一个最基本的原则:判断新创建的 Widget 和老的 Widget 是否是同一个类型。如果不是同一个类型,那就把 Widget、Element、RenderObject 分别从它们的树(包括它们的子树)上移除,然后创建新的对象。如果是一个类型,那就仅仅修改 RenderObject中的配置,然后接着遍历其他对象。

    在我们的例子中,SimpleApp Widget 是和原来一样的类型,它的配置也是和原来的 SimpleAppRender 一样,所以什么都不会发生。下一个 item 在 Widget 树中是 SimpleContainer Widget,它的类型和原来是一样的,但是它的颜色变化了,RenderObject的配置发生变化了。因为SimContainer 仍然需要一个SimpleContainerRender 来渲染,因此 Flutter 只是更新了SimpleContainerRender的颜色属性,然后要求它重新渲染。其他的对象保持不变。

    当 widget 树重新创建之后的状态如下图所示(需要注意的是,Element 和 RenderObject 依然是同一个实例对象)

     

     

     

    这个过程是非常快的,因为Flutter 非常擅长创建那些轻量级的 Widgets。那些重量级的 RenderObject 则是保持不变,直到与其相对应类型的 Widget 从 Widget 树中被移除。那如果Widget的类型发生改变了会发生什么?

    比如将 SimpleText 替换为 SimpleButton

     

     

    和上面一样,Flutter 会重建 Widget 树,并遍历这棵树,然后比较 Widget 的类型是否和 RenderObject 中的对象对应。

    此时三颗树的状态如下所示,改变类型的 Widget 对应的 Element 和 SimpleTextRender 已经被移除了

     

     

    因为SimpleButton 的类型与 Element 树中相对应位置的 Element 的类型不同,Flutter将会从另外两棵树上删除对应的 Element 和相对应的 SimpleTextRender。然后Flutter 将会重建与 SimpleButton 相对应的 Element 和 RenderObject 对象实例。

    最终的状态如下

     

     

    然后新的 RenderObject 树已经被重建,然后重新布局并绘制在屏幕上面。在这里面,Flutter 做了大量优化工作并且其使用的缓存策略,能够让我们不必手动的对这些对象进行管理。

    四、总结

    现在你应该对 Flutter 是如何工作的,为什么能够渲染复杂的布局并且运行的还很流畅有了一定的了解,这里面还没有讲到 State,Flutter 引入了 State 来提升了这个过程的整体性能,今天暂时不对此进行讨论了,希望这篇文章能够帮助你理解 Flutter 框架。

     

    推荐阅读

    Widget、RenderObject 与 Element


    欢迎关注「Flutter 编程开发」微信公众号 。

     


    作者:Flutter编程开发
    链接:https://juejin.cn/post/6854573211108966408
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • Flutter框架

    2020-02-19 12:05:23
    Flutter框架出现之前,主要有以下几个移动App跨平台开发框架:Cordova、Ionic、AppCan、Dcloud、APICloud、React Native。虽然有那么多框架,但是它们的原理都是使用HTML、CSS和JavaScript进行移动App开发,多平台...

    转自:https://www.jianshu.com/p/ebbd7a68936a

    在Flutter框架出现之前,主要有以下几个移动App跨平台开发框架:Cordova、Ionic、AppCan、Dcloud、APICloud、React Native。虽然有那么多框架,但是它们的原理都是使用HTML、CSS和JavaScript进行移动App开发,多平台共用一套代码,提供了丰富的主流UI库、用来调用原生API的JavaScript API包装器,同时还提供App打包、发布的工具或服务。由于这些跨平台开发框架是使用标准Web技术开发,所以它们打包出来的App在性能上,多少都会比原生App差上不少,这也是移动App跨平台开发技术一直不温不火的原因。

    在决定学习一门新技术之前,我们总会拿它与同类技术进行对比,确保不会把宝贵的学习时间浪费在无用的技术上。所以,接下来我们将在对比中认识我们将要学习的Flutter框架。首先是Flutter实现跨平台开发的原理,Flutter与现有的移动App跨平台开发框架都不一样,Flutter不是使用标准Web技术,而是借助可移植的图形加速渲染引擎、高性能的本地ARM代码,并以此实现跨设备、跨平台的高质量用户体验。

    1.1.1.1

    由上我们可以得知,使用Flutter开发的跨平台移动App,性能是可以与原生App一模一样的。你以为这样就完了吗?不不不,Flutter框架的能力不止于此!Flutter应用的性能甚至可以比原生App更加优秀,因为Flutter框架针对性能方面进行了优化。

    传统的Web应用中会有成千上万数量个DOM节点,所以更新的时候会非常琐碎、频繁,使页面加载缓慢,所以现代的Web应用开始使用虚拟DOM技术来提高页面更新的速度,用一个虚拟DOM,而不是直接调用类似.getElementById的方法,只操作JavaScript对象,然后再把更改的部分更新到真实DOM,这样是相当方便的。但是添加了虚拟DOM意味着更多的代码,而且在一个DOM节点相对较少的页面中用虚拟DOM,实际上有可能会更慢。

    1.1.1.2

    不仅是现代的Web应用,其实目前主流的Android于iOS应用也是大量使用类似虚拟DOM的技术,即虚拟控件,而且得益于移动设备的性能优势,使虚拟DOM这种形式的响应式框架的优点发挥到极致,使得开发者忽略了该模式的缺点。

    1.1.1.3

    就在平台与开发者满足于这种以硬件性能优势来解决软件框架的性能缺陷时,Flutter横空出世!在Flutter的响应式框架中,控件树中的控件直接通过可移植的图形加速渲染引擎、高性能的本地ARM代码进行绘制,不再需要通过虚拟DOM或虚拟控件、真实DOM或平台控件这些中间对象来绘制。Flutter响应式框架通过“无中间商赚差价”的方式直接利用硬件的所有性能,所以正如前面所说的,Flutter应用的性能比原生App更加优秀。

    1.1.1.4

    Flutter的优秀还不止如此,使用Flutter开发的应用能以60 FPS运行,这是现有的移动端游戏都难以实现的一个性能指标,例如王者荣耀也只能以40左右的FPS运行,所以使用Flutter创建的用户界面,性能远远优于其他跨平台框架。现在开始学习Flutter,就是对未来的投资!



    作者:何小有
    链接:https://www.jianshu.com/p/ebbd7a68936a
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • Flutter 框架实现原理

    千次阅读 2020-08-05 14:02:31
    文章目录Flutter 框架实现原理UI 构建原理WidgetElementRenderObjectLayerUI构建过程视频课程 Flutter 框架实现原理 简版架构图 Framework:一个纯 Dart代码的 SDK。它实现了一套基础库, 包含动画、绘制和手势...

    博主相关文章列表
    Flutter 框架实现原理
    Flutter 框架层启动源码剖析
    Flutter 页面更新流程剖析
    Flutter 事件处理源码剖析
    Flutter 路由源码剖析
    Flutter 安卓平台源码剖析(一)
    Flutter 自定义控件之RenderObject

    Flutter 框架实现原理

    简版架构图

    简版图

    • Framework:一个纯 Dart代码的 SDK。它实现了一套基础库, 包含动画、绘制和手势处理。并基于绘制封装了一套Widget控件库,这套控件库还根据 MaterialCupertino两种设计风格进行了风格化区分。
    • Engine:一个 C++实现的 SDK。其包含了 Skia引擎、Dart运行时、文字排版引擎等。在安卓上,系统自带了Skia,在iOS上,则需要APP打包Skia库,这会导致Flutter开发的iOS应用安装包体积更大。 Dart运行时则可以以 JIT、JIT Snapshot 或者 AOT的模式运行 Dart代码。

    其中 dart:ui库是对Engine中Skia库的C++接口的绑定。向上层提供了 windowtextcanvas等通用的绘制能力,通过 dart:ui库就能使用Dart代码操作Skia绘制引擎。所以我们实际上可以通过实例化dart:ui包中的类(例如Canvas、Paint等)来绘制界面。然而,除了绘制,还要考虑到协调布局和响应触摸等情况,这一切实现起来都异常麻烦,这也正是Framework帮我们做的事。

    渲染层Rendering是在dart:ui库之上的第一个抽象层,它为你做了所有繁重的数学工作(如跟踪计算坐标等)。为了做到这一点,它使用RenderObject对象,该对象是真正绘制到屏幕上的渲染对象。由这些RenderObject组成的树处理真正的布局和绘制。

    Engine之下,还包含一层Shell。这个单词是 “壳”的意思,这个壳组合了Dart运行时、第三方工具库、平台特性等,实现在不同平台调用和运行 Flutter应用。

    总的来说, dart:ui给 Dart提供了绘制能力,Dart运行时为 Flutter提供了执行Dart代码的能力,而Shell将他们组合起来,并且将生成的数据渲染到不同的平台。

    UI 构建原理

    Flutter 的渲染流水线

    屏幕上的每一帧的绘制过程,实际上是Engine通过接收的VSync信号不断地触发帧的绘制

    从构建到渲染流程

    构建UI体系的四棵树

    Widget

    是 Flutter中UI开发的基本单元。 一个Widget里面通常存储了视图的配置信息,包括布局、属性等。我们可以把它理解为一个UI元素的配置文件,类似于原生开发中的xml描述文件。所谓Widget树,就是我们手动编写的结构化的Widget代码,当被加载到内存时,就形成了Widget树。

    Flutter中,除了Widget树是我们自己编写的,另外三棵树都需要借助Widget树构建出来。

    Element

    该对象实际上是一个上下文,将WidgetRenderObject映射关联起来。通过遍历Widget控件树来构建一个Element树结构。在原生开发中没有对应的概念,它的概念更接近于Web前端中的虚拟DOM,主要做的事情也是比较前后两次Widget的差异来决定如何更新真实的渲染对象树(RenderObject树)。

    RenderObject

    真正的渲染对象。最接近原生开发中的UI控件元素。它主要处理UI构建过程中的布局与绘制。它依赖于Element树来生成一颗RenderObject树。

    Layer

    该对象表示的是图层的意思。通常一棵RenderObject树经过绘制之后,就会生成一个Layer对象,但并不是所有RenderObject都会绘制到一个Layer中,某些情况下,例如不同路由页面,就会绘制到不同的Layer图层中。这些Layer对象组成的结构就是Layer树。

    在绘制时,会根据 isRepaintBoundary是否为 true来决定是否绘制到新的图层。了解这一点,我们就可以使用RepaintBoundary 控件在外层包裹,然后通过设置该控件的isRepaintBoundary属性来提升绘制性能。因为 isRepaintBoundarytrue 时,会形成了独立的 Layer,这样其他控件发生频繁的改变时,就不会影响到独立的图层,这个独立的图层也不会发生重绘,节省性能开销。

    最后的最后,所有图层都交由 GPU 来负责合成并上屏显示。在渲染流程的最后两个步骤中,正是合成与光栅化。

    UI构建过程

    光栅化

    合成已经理解了,那么什么是光栅化呢?

    光栅化也称栅格化,是指将几何数据经过一系列变换后最终转换为像素,从而呈现在显示设备上的过程。光栅化的本质是坐标变换、几何离散化。

    视频课程

    本篇博客视频内容可访问B站链接 框架实现原理 您觉得有帮助,别忘了点赞哦

    如需要获取完整的Flutter全栈式开发课程,请 点击跳转
    qr_adv

    展开全文
  • Flutter框架优缺点

    2021-10-19 16:33:00
    A、混合开发中,最接近原生开发的框架; B、性能强大,流畅; C、优秀的路由设计; D、优秀的动画设计; E、简单易学,Dart语言更具优势; F、跨多种平台,减少开发成本;支持插件,可以访问原生系统的调用。 2、...
  • 什么是flutter框架

    2020-11-17 16:37:02
    Flutter 起初是一个开源的移动 UI 框架,帮助开发者构建原生外观的 Android 和 iOS 应用。但不久前,Flutter开始支持同一个代码库开发桌面、嵌入式、移动和Web应用。 尽管它的竞争对手React Native的使用范围仍然...
  • flutter_boilerplate_app 我的启动Flutter应用程序模板。
  • Flutter篇 flutter框架优缺点

    千次阅读 2020-12-01 17:21:04
    A、混合开发中,最接近原生开发的框架; B、性能强大,流畅; C、优秀的路由设计; D、优秀的动画设计; E、简单易学,Dart语言更具优势; F、跨多种平台,减少开发成本;支持插件,可以访问原生系统的调用。 2、...
  • flutter框架结构图

    2020-12-10 16:19:50
    Flutter的架构主要分成三层:Framework,Engine和Embedder。 框架Framwork 这一层纯dart实现,使用了两种设计风格Material Design和Cupertino(针对iOS)风格。 Widgets层:一套基础组件库。 Rendering层:ui布局渲染...
  • 安卓开发教程(Flutter框架) 作者:蔡熙贝 现在是北京时间:
  • flutter框架搭建

    千次阅读 2019-03-27 14:22:34
    1.安装java环境(安装jdk) ... 下载完成后进行安装,直接下一步下一步就可以了。一般安装到系统盘,也就是C盘。安装完成到命令行(cmd)里输入java,能出现下图中的结果,说明安装成功。...2.下载flutter JDK...
  • 简单说一下Flutter框架

    2021-09-09 11:10:43
    Flutter框架出现之前,主要有以下几个移动App跨平台开发框架:Cordova、Ionic、AppCan、Dcloud、APICloud、React Native。虽然有那么多框架,但是它们的原理都是使用HTML、CSS和JavaScript进行移动App开发,多平台...
  • Flutter框架的优点

    2020-12-05 23:34:19
    Flutter对比weex和react native相比,性能的强大是有目共睹的。基于dom树渲染原生组件,很难与直接在原生视图上绘图比肩性能,Google作为一个轮子大厂,直接在两个平台上重写了各自的UIKit,对接到平台底层,减少UI...
  • Flutter框架的自定义标签栏小部件。 该设计灵感来自Rally项目(材料设计研究之一)。 入门 将包添加到pubspec.yaml dependencies : ... shifting_tabbar : ^0.3.1 导入包裹 import 'package:shifting_tabbar/...
  • A、混合开发中,最接近原生开发的框架; B、性能强大,流畅; C、优秀的路由设计; D、优秀的动画设计; E、简单易学,Dart语言更具优势; F、跨多种平台,减少开发成本;支持插件,可以访问原生系统的调用。 2、...
  • 【安卓开发系列 -- APP】Flutter -- Flutter 框架与绘制原理简介 【1】Flutter 框架的整体架构 【2】Flutter 绘制原理简介 【2.1】屏幕显示图像的基本原理 【2.2】Flutter 的显示方式 【2.3】Flutter 的...
  • Flutter 是由零散的组件组成的,组件就和平时Android开发中看见的控件是一样的,相当于ImageView\TextView 等,在使用Flutter 之前,有必要了解Flutter的组件, 上一篇Mac pro 搭建Flutter 开发环境和第一个...
  • 颤振包 此存储库包含Flutter框架软件包的源代码。
  • 是使用构建的100%免费的Flutter开源极简UI框架,使Flutter开发比以往任何时候都更加轻松愉快。 受到Tailwindcss和SwiftUI的启发。 "Web" .text.white.xl4.bold.center. makeCentered ().box.roundedLg.red500....
  • Flutter框架分析(一)--架构总览前言Flutter体系架构不同跨平台技术对比小结 前言 Flutter是Google打造的高性能、跨平台的UI框架。它可以给开发者提供简单、高效的方式来构建和部署跨平台、高性能移动应用;给用户...
  • 该项目是Flutter应用程序的起点。 如果这是您的第一个Flutter项目,那么有一些资源可以帮助您入门: 要获得Flutter入门方面的帮助,请查看我们的,其中提供了教程,示例,有关移动开发的指南以及完整的API参考。
  • Flutter框架简述

    千次阅读 2018-01-05 18:45:56
    概念Flutter是一个移动应用程序的软件开发工具包(SDK),具有以下特征: 跨平台应用的框架, 没有使用WebView或者系统平台自带的控件,使用自身的高性能渲染引擎自绘 简化版的浏览器,最大限度在android和ios上统一...
  • Flutter项目底层框架。用于开发Flutter项目的时候搭建最底层的框架搭建,这个框架是万能的,非常好用,也很值得参考。
  • 使用Dart在Flutter框架中实现一些设计模式。 我们假设您已经在Flutter开发方面拥有出色的经验,并且可以提高您的编码技能。 创作模式 辛格尔顿 工厂方法 行为模式 结构模式 深入了解Flutter MVC 最有价值球员 ...
  • Flutter框架调研

    2021-08-19 11:54:33
    目录 1 背景介绍 原生开发 VS 跨平台技术 2 Flutter简介 Flutter框架结构 3 Flutter特性 开发效率高 高性能 类型安全 Flutter与原生APP的比较 Flutter与React Native的比较 4 Flutter入门实践 Dart语法 5 Flutter...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,797
精华内容 8,318
热门标签
关键字:

flutter框架