flutter是跨平台的UI框架,非UI层面的任务,通过插件机制与iOS或Android通讯。
UIView 与 Widget
UIView是iOS中最常用的视图控件,Widget并不完全等同于UIView,它可以被称为“声明和构造 UI 的方法”。UIView是可变的,直接对UIView修改并不会导致重新创建实例。Widget不可变,只能通过修改Widget的state来使其改变。
两种Widget:有状态的 StatefulWidget
和无状态的StatelessWidget
, StatefulWidget
有一个State
对象,用来存储状态。
示例:Text,Text继承自无状态Widget:class Text extends StatelessWidget
,只能渲染初始化时的内容。想变更Text内容,需要放到StatefulWidget
中:
1 | class ChangedText extends StatefulWidget {//有状态的StatefulWidget |
修改变量要在setState()
方法中修改,会为State对象触发build()
方法,会让UI更新。如果不在该方法中,直接更改变量值,可更改变量,UI不会更新。
VS Code支持代码块,输入state时能快速创建自定义StatefulWidget
布局约束
iOS中有storybody和xib布局,直接对视图设置约束,或者用代码设置约束,来适配屏幕。在flutter中也可以通过代码设置约束。
比如自定义按钮可以添加padding:
1 | FlatButton( |
添加移除组件
在iOS原生开发中,可以使用 addSubview()
和removeFromSuperview()
添加移除控件,flutter中没有这类方法。flutter的视图添加移除可以动态解决,在Widget中动态添加视图,未添加上的便是移除了。Widget不可变,更改State后会重绘一个Widget代替原来的Widget,所以动态添加便完成了添加移除组件操作。
示例代码:
1 | class _ChangedTextState extends State<ChangedText> { |
声明式UI
通过上面的组件添加移除可以看出flutter的UI操作和原生iOS的区别,原生iOS对UI操作,是对UI组件直接进行命令操作,比如:执行addSubview()
和removeFromSuperview()
添加移除UI。
在flutter中Widget是不可变的,只有调用setState()
方法触发Widget重建,这时是构造了一个新的Widget实例。
框架使用 RenderObjects 管理传统 UI 对象的职责(比如维护布局的状态)。 RenderObjects 在帧之间保持不变, Flutter 的轻量级 widget 通知框架在状态之间修改 RenderObjects, Flutter 框架则处理其余部分。
这就是flutter中的声明式UI
demo的完整代码见工程中的 flutter_ios