0%

Flutter笔记4-UI框架

flutter是跨平台的UI框架,非UI层面的任务,通过插件机制与iOS或Android通讯。

UIView 与 Widget

UIView是iOS中最常用的视图控件,Widget并不完全等同于UIView,它可以被称为“声明和构造 UI 的方法”。UIView是可变的,直接对UIView修改并不会导致重新创建实例。Widget不可变,只能通过修改Widget的state来使其改变。

两种Widget:有状态的 StatefulWidget 和无状态的StatelessWidgetStatefulWidget有一个State对象,用来存储状态。

示例:Text,Text继承自无状态Widget:class Text extends StatelessWidget,只能渲染初始化时的内容。想变更Text内容,需要放到StatefulWidget中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class ChangedText extends StatefulWidget {//有状态的StatefulWidget
@override
_ChangedTextState createState() => _ChangedTextState();
}

class _ChangedTextState extends State<ChangedText> {
String titleText = 'hello world';//初始化
void _textBtnClik() {
setState(() {
titleText = 'hello flutter';//修改变量
});
}
Widget _changedTextView() {
return Center(
child: Column (
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(titleText),//Text赋值变量
FloatingActionButton(
onPressed: _textBtnClik, //点击按钮修改变量
child: Icon(Icons.add_circle),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('home'),
),
body: _changedTextView()
);
}
}

修改变量要在setState()方法中修改,会为State对象触发build()方法,会让UI更新。如果不在该方法中,直接更改变量值,可更改变量,UI不会更新。

VS Code支持代码块,输入state时能快速创建自定义StatefulWidget

布局约束

iOS中有storybody和xib布局,直接对视图设置约束,或者用代码设置约束,来适配屏幕。在flutter中也可以通过代码设置约束。

比如自定义按钮可以添加padding:

1
2
3
4
5
6
FlatButton(
color: Colors.blue,
padding: EdgeInsets.only(top:10,bottom: 10, left: 60, right: 60),
child: Text('Btn'),
onPressed: _textBtnClik,
),

添加移除组件

在iOS原生开发中,可以使用 addSubview()removeFromSuperview() 添加移除控件,flutter中没有这类方法。flutter的视图添加移除可以动态解决,在Widget中动态添加视图,未添加上的便是移除了。Widget不可变,更改State后会重绘一个Widget代替原来的Widget,所以动态添加便完成了添加移除组件操作。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class _ChangedTextState extends State<ChangedText> {
int index = 0;
String text = 'hello wrold';
bool textBool = true;
_textBtnClik() {
setState(() {
index ++;
textBool = !textBool;//bool值控制添加组件
});
}
_viewShow() {//返回不同的组件
if (textBool) {
return Text(text);
} else {
return Text('$index');
}
}
Widget _changedTextView() {
return Center(
child:
Column (
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_viewShow(),//添加组件
FlatButton(
color: Colors.blue,
padding: EdgeInsets.only(top:10,bottom: 10, left: 60, right: 60),
child: Text('Btn'),
onPressed: _textBtnClik, //按钮控制bool值
),
],
),
);
}

声明式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

打赏作者一杯咖啡