Flutter和Dart系列三:视图与数据如何关联
今天我们就从零开始写代码吧,要实现的功能很简单,就是:点击屏幕上的FAB,实现文本内容替换。 新建一个Flutter项目,将main.dart中的代码都删除,我们从头开始写。
-
导包
1
2 1import "package:flutter/material.dart";
2
-
编写主函数:
1
2
3
4
5
6
7
8
9
10
11 1void main(){
2 runApp(SampleApp());
3}
4
5class SampleApp extends StatelessWidget{
6 @override
7 Widget build(BuildContext context){
8 //…….
9 }
10}
11
- a. runApp():
Inflate the given widget and attach it to the screen.
也就是说,这个地方需要传入一个Widget,并且这个Widget是会显示在屏幕上。告诉大家,这里传入的widget就是root widget。这里有个概念需要大家知道一下:widget tree。觉得也并不陌生,想什么View Tree,DOM Tree,这种涉及到控件设计的,肯定是使用树这种数据结构来组织的。
- b. Widget:
它的地位可以类比Android的View:
In Flutter, almost everything is a widget,including alignment, padding, and layout。
Widget又可以分为两大类:StatelessWidget和StatefulWidget。顾名思义,一个是不带状态的Widget,一个是带状态的Widget。那么什么叫不带状态呢?就是不会变化。如果你的widget在进行网络请求之后或者用户操作之后会产生变化,那么这个时候就需要使用StatefulWidget。更本质地说,是与之对应的数据的变化,才会引起UI的变化。在Android开发中,尽管你采用mvc、mvp模式去架构app,但是你还是需要持有需要变化UI对象的引用,然后将数据的变化通过这个引用设置到UI控件上,你还是需要和UI对象打交道。可能这么说你还不清楚,我们通过代码来帮助理解。
-
继续添加代码,实现SampleApp的build方法:
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
37
38 1@override
2Widget build(BuildContext context){
3 return MaterialApp(
4 title: “Sample App”,
5 debugShowCheckedModeBanner: false,
6 theme: ThemeData(
7 primaryColor: Colors.blue),
8 home: SampleAppPage(),
9 );
10}
11
12class SampleAppPage extends StatefulWidget{
13 @override
14 State<StatefulWidget> createState(){
15 return SampleAppPageState();
16 }
17
18}
19
20class SampleAppPageState extends State<SampleAppPage>{
21 Strign _textToShow = “I Like Flutter”;
22
23 @override
24 Widget build(BuildContext context){
25 return Scaffold(
26 appBar: AppBar(
27 title: Text(“Sample App”),
28 ),
29 body: Center(child: Text(_textToShow)),
30 floatingActionButton: FloatingActionButton(
31 onPressed: _updateText,
32 tooltip: “Update Text”,
33 child: Icon(Icons.update),
34 ),
35 );
36 }
37}
38
写到这个地方呢,这个_updateText肯定会报错,继续去实现这个方法,也是这篇文章的核心:
1
2
3
4
5
6 1void _updateText() {
2 setState(() {
3 _textToShow = “Flutter is Awesome!”;
4 });
5}
6
这里呢,大家可以不用去纠结具体某个Widget的作用,以及某些属性的作用,这不是我们现在的重点,后面我们会重点去学习。 运行起来,这里就不去截图了。
效果已经出来了。现在我们再回想起前面我们关于Widget那块的描述。 假设这个地方是使用Android去实现: 在_updateText()方法里,我们肯定需要拿到TextView对象,然后通过setText()方法,将新的文本内容设置到TextView上。 再来看看Flutter中的关于这块的处理:
1
2
3
4 1setState((){
2 //直接变换数据的值,不需要所谓的TextView对象
3})
4
这样,我们只需要关注数据的变化,UI的变化伴随着数据的变化也发生了变化。从某种意义上说,这是一个单向的mvvm,setState实际上和微信小程序中的setData是有类似的作用。