Flutter使用Dart
作为开发语言,在开发理念上也是偏向于网页开发的(虽然我没开发过网页)。
应用的基础构成
Flutter的执行起点为main()
函数,然后通过runApp()
方法启动页面。
目前Flutter提供了两个App类,分别为安卓风格的MaterialApp
和IOS风格的CupertinoApp
,一般runApp()
函数都是传入这两个App类的实例。
App类有点像Android中的Application
,但它承载了更多的功能,比如设置应用主题、应用在后台列表中的颜色、名称等。值得一提的是,App类也属于Widget
,所以按Widget
的理念去理解即可。
通过App类的home
参数,我们传入一个Widget,即表示我们在Flutter的首页所显示的内容就是该Widget。一般而言,我们会传入Scaffold
作为App类的home
。
在Flutter中,每个页面都由Scaffold
构成(或者说承载),类似于Android中的Activity。Scaffold
中可以设置一个页面的app bar、bottom sheet等,其中最主要的是widget
类型的body
参数,可以理解为类似HTML中的<body>
标签,此处显示的就是当前页面的本体。
所以一个Flutter的启动链条,就是:
main.dart –> main() –> 调用runApp() –> 生成App类 –> home参数传入生成的Scaffold实例 –> body参数传入自己实现的页面(widget)
页面跳转
要在Flutter中跳转到另一个页面,则需要通过路由Navigator
实现。
在Android中也有页面路由的概念,但是一般是自己实现的。Navigator
更类似于后台维护一个页面的栈(或一个map)。
上面说到,每个页面都由Scaffold
承载。而为了使用Navigator
,需要在新页面的外层封装一个PageRoute
,这个PageRoute
类似于我们使用容器去保存一些数据时,为了方便管理、设置不同属性,会为数据提供一个包装类Wrapper一样。在不同的App下有不同的PageRoute
,比如在Material
下就用MaterialPageRoute
。
当我们要跳转到第二个页面时,只需要调用Navigator.push()
方法即可,其内部会记录各页面之前的跳转顺序,所以我们按Back键回退时,会自动回到第一个页面。
轻量化Widget
在Android中,创建一个控件代价不算大,但如果我们要刷新一个控件,我们更倾向于对控件的参数、内容进行更改,而不是删除再重新创建一个。
Flutter引入了万物皆Widget的概念,即所有的内容都是一层控件。
Flutter对Widget的创建开销很小,而且会在其重新创建时与旧的Widget进行比较,仅对差异部分进行重绘。所以Flutter和Android原生的开发理念不同——Android依然遵循着万物皆对象的概念,其控件相对之下显得略“重”,鼓励我们复用、刷新控件来达到数据更新显示;而Flutter鼓励我们在数据更新时直接重建Widget,不需要考虑new一个Widget的开销问题。
State和StatefulWidget
Flutter的Widget分为两种:StatelessWidget
和StatefulWidget
,前者表示不会变更的控件,比如一段不会变的文字、图标等;后者表示其会根据数据、事件动态刷新变更,所以它需要配合State
一起使用。
State
和StatefulWidget
相互绑定在一起。创建StatefulWidget
时,将调用createState()
创建其指定的State
。其指定的State
只会创建一次,内部变量会一直在Widget Tree销毁前保存着。setState()
函数只会让State
重新build其绑定的Widget,不会再创建State
。
Parent Widget和Child Widget之间的通信
按照Flutter的官方说法,Child Widget通过监听函数(callback)向上通知Parent Widget,Parent Widget通过监听函数收到通知后,调用setState()
方法改变数据状态,然后重新创建Child Widget。
简单,粗暴,一切归于重建,遇事不决,先重建Widget再说。
评论