是时候搞一点新东西了
其实我在去年就对 Flutter 有所了解,当时的 Flutter 已经可以和 react native 相互竞争了,但是但是 flutter 生态化没有完全建立起来,根本和 RN 比不了,虽然在 Github 有了几十万 star 但是也只是作为 Android 和 iOS 之间跨平台的一种方案。
然而在2019年5月,谷歌在其官方博客宣布,Flutter 已支持移动、Web、桌面和嵌入式设备,这意味着它正式成为了支持多平台的轻量级 UI 框架。
所以,是时候搞一点新东西了。
Flutter 优势
我简单说一下 Flutter 的优势,首先就是跨平台特性;其次,其采用 Dart 语言,这个语言内部机制决定了 Flutter 有一个很优秀的功能——热重载,也就是说改动代码后不需要重新运行应用(Init…resolve…),代码的改动可以直接作用于正在运行的程序;最后一点就是渲染,他采用 GPU 渲染应用,体验上我完全不输 RN 原生应用。
Flutter 配置
可以参照官方文档进行配置:
https://flutter-io.cn/docs
我踩到的坑:
国内用户提示加的那两个环境变量(两个网站)一定要加在系统变量中,不要加在用户变量,会由于权限问题导致没有效果,导致新建 Flutter 出现卡死情况(网站上不去、解析不了当然卡死)
构建自己的第一个 flutter App(假的)
项目地址:https://github.com/AllenMistake/flutter_app
之所以是假的,是因为完全参考官方给出的示例代码,毕竟,我刚刚上手,API都不懂,怎么码代码嘛,还是要一步一步来,不要一口吃个胖子。
我在这里分析几个源码中我认为比较重点的几个点:
单行函数
1 | void main() => runApp(new MyApp()); |
=>在dart中表示单行函数或方法,算是提高代码简洁度的一个语法糖吧。
widget结构分析
首先我们看一下最初的源码
1 | class MyApp extends StatelessWidget { |
Scaffold 是 Material library 中提供的一个 widget,它提供了默认的导航栏、标题和包含主屏幕 widget 树的 body 属性。widget 树可以很复杂。
一个 widget 的主要工作是提供一个 build() 方法(总是要重写,类似于activity中的 onCreate)来描述如何根据其他较低级别的 widgets 来显示自己。
本示例中的 body 的 widget 树中包含了一个 Center widget,Center widget 又包含一个 Text 子 widget,Center widget 可以将其子 widget 树对其到屏幕中心。
添加依赖
添加依赖在 pubspec.yaml 中,然后点击右上角出现的Packages get,当然别忘了在主程序中引入包。
添加一个 Stateful widget
Stateless widgets 是不可变的,这意味着它们的属性不能改变——所有的值都是 final。
Stateful widgets 持有的状态可能在 widget 生命周期中发生变化,实现一个 stateful widget 至少需要两个类:1)一个 StatefulWidget 类;2)一个 State 类,StatefulWidget 类本身是不变的,但是 State 类在 widget 生命周期中始终存在。
万物皆是 widget
1 | return new ListTile( |
这个代码中 ListTile 和 Text 都是 widget 他们各自的属性用括号括起来,记住,每个属性写完之后要加逗号,这个很容易忘。
二阶段:加入Icon和跳转页面
我们看一下最终结构关系图
来看看第二阶段学习了哪些内容吧
在 stateful widget 上添加交互
1 | Widget _buildRow(WordPair pair) { |
在 onTap
属性中,我们添加了点击事件的逻辑。我们在 _buildRow 中让心形 ❤️图标变得可以点击。如果单词条目已经添加到收藏夹中, 再次点击它将其从收藏夹中删除。当心形 ❤️图标被点击时,函数调用 setState() 通知框架状态已经改变。
提示: 在 Flutter 的响应式风格的框架中,调用 setState() 会为 State 对象触发 build() 方法,从而导致对 UI 的更新
导航到第二个页面;
1 | void _pushSaved() { |
添加一个显示收藏夹内容的新页面(在 Flutter 中称为路由[route])。
在 Flutter 中,Navigator (导航器)管理应用程序的路由栈。将路由推入(push)到导航器的栈中,将会显示更新为该路由页面。 从导航器的栈中弹出(pop)路由,将显示返回到前一个路由。
我们在 RandomWordsState 的 build 方法中为 AppBar 添加一个列表图标。当用户点击列表图标时,包含收藏夹的新路由页面入栈显示。
添加 Navigator.push
调用,这会使路由入栈(以后路由入栈均指推入到导航管理器的栈)
在新的 route(路由)页面中显示收藏的内容。Navigator(导航器)会在应用栏中自动添加一个”返回”按钮,无需调用Navigator.pop,点击后退按钮就会返回到主页路由。
接下来,添加 MaterialPageRoute 及其 builder。 现在,添加生成 ListTile 行的代码,ListTile 的 divideTiles()
方法在每个 ListTile 之间添加 1 像素的分割线。 该 divided
变量持有最终的列表项,并通过 toList()
方法非常方便的转换成列表显示。
builder 返回一个 Scaffold,其中包含名为”Saved Suggestions”的新路由的应用栏。新路由的body 由包含 ListTiles 行的 ListView 组成;每行之间通过一个分隔线分隔。
最终,我们可以通过 Flutter Inspector 查看 Widget Tree 具体结构