正如第一篇文章所说的 Flutter 是一个「框架」,可以用来开发跨平台原生的应用程序。
整个 Flutter的架构图:
由上到下分别是框架层、引擎层、嵌入层
从最下面两层的 Animation、Painting、Gestures 及Foundation结合起来就 dart:ui
这个library,这层提供了基本常用的抽象API像是:绘制画面、动画、输入等等。所以这层其实也就是直接操作引擎画面中哪个pixel要绘制什麽、这动画会要往哪个方向移动几pixel之类非常基础的操作。
Rendering层也就是RenderObject Tree所在的地方,在这层会利用 RenderObjects
来协助画面的更新、渲染等等当我们动态的更新资料时,这层会帮我计算我们所需要重新绘制的部分然後重新渲然,而我们不用直接呼叫dart:ui
相关的api。
Widgets层则是提供一些基本常用widget,并在此基础提供了 Material 及 Cupertino 这两个设计规范的widget。
是用纯C++实作的SDK,透过SKIA引擎将真正的绘制逻辑实作在这层,而dart:ui
最终则是调用这层的API
而嵌入层则是将flutter安装到各大平台的嵌入器,而这个嵌入器是会根据不同平台而使用不同的程序语言实作,像是Android会用JAVA、iOS用Objective-C。但这个嵌入器除了看是安装整个flutter app 也可以把flutter code 变成module嵌入其他已经用其他原生语言开发的专案。
这边只是让各位读者整个Flutter有点初步的印象,实际上开发时应该是都聚焦在框架层,而且也当你需要了解一些进阶的问题时才会认真的去看这些层帮我们做了什麽事,像是想要知道 key
到底做了什麽事、状态更新时哪些东西会被销毁或重新建立之类的问题。
在官方文件里有写到 Flutter 到底运用了哪些概念
我个人认为有几点特别重要
UI = F(state) 其实就是Reactive programming加上Declarative programming的概念,我的画面是根据「状态」变更而响应式的去重新绘制画面,而且我不用去管要如何重新绘制,我只要知道他要变更什麽。
我只要将我需要动态变更的资料放进widget里,资料变更时他自然就会重新绘制,当然还需要一个一个有办法「反应」资料变化的东西存在,可能是state本身、observer等等之类。
Text('${someAPIData.filed1}',style:textStyle)
简而言之,我们不需要在变更资料後还要手动去trigger UI的re-render。
在 Flutter 中所有的有关显示的东西都是widget,容器(像是container)是widget、按钮是widget、layout相关(像是padding之类)也是widget,而且也可以像react一样,我们可以藉由拆分components(widgets)来建构我们的应用程序。
widget 也是一种 immutable的 UI 宣告方式,意思是我们的widget本身其实immutable,他建立完之後就是不可变的,这也就是为什麽所有widget为什麽都是要用 final
来宣告参数,以及为什麽 StatefulWidget
的build()
是放在 State
而不是 StatefulWidget
本身的class里面。
但需要这样设计的详细原因等到之後有机会再说,这边稍微说一下我们实际看到渲染出来的不是widget而是rednerObject。
承上面所说在Flutter中每个小功能都是一个widget,所以当我们想要padding 我们就用 Padding
包住现有的 widget ,想要手势操作就用 GestureDetector
。讲白一点我们把可设定的属性都拆成各个widget然後我们再自己层层架构。
但这样做的好处是什麽?我们需要什麽就拿什麽,不用去管哪个widget只有开哪些参数。
但坏处也很明显就是我们的程序码的巢状结构会十分十分的深,这点也是许多人诟病flutter的一点,毕竟不像是写网页那样我可能是一个 div
就已经将间距、颜色、资料绑定、事件监听都给通通结合在一起了,当然会在不同地方实作这些需求,但至少这个div
在 jsx
or 其他样板引擎应该都只是一层tag而已。
但一些真的很常用的参数其实还是可以在 Container
这个widget一起做掉像是 alignment
、 padding
、 width
、 hight
等等属性。至於这样子到底有没有跟aggressive composition这个理念冲突我觉得这是 flutter 保留的弹性,如果我真的一次要设定那麽多属性那就直接在Container
设定就好,如果只要设定padding 那我可能就wrap Padding
就好
今天终於开始进入 Flutter 的篇章,明天开始我们就要建立第一个 Flutter 专案。
参考资料
<<: Day 12: ML APIs | Google Cloud
前面我们谈了,coroutine的coroutineScope、继承、异常处理和取消,也在文中提到了...
分析资料集 资料集来源: https://opendata.culture.tw/frontsite...
延续前一天的程序码,在程序码後面加上以下三行程序码,他就会用前一天做出来的日收盘价计算出均线(预设算...
战斗实际制作Part02 承接昨天的攻击功能制作。拿取到定位点後要转换成Raycast再进行侦测。为...
1.将要遮罩的Shape>Pre compose 2.最後就是最简单的部分,找张图用遮罩就完成...