Google自2017年第一次提出Flutter, 到2018年Beta, 再加之RN的各种风波与问题, 使得Flutter的热度不断上升, 国内不少公司都公布Flutter在其产品中的应用, 如美团, 闲鱼等.
前言Flutter作为跨平台框架, 常常被人拿出来与React Native, 以及Xamarin进行对比, 除了大家都是跨平台框架之外且能达到近乎Native的体验之外, Flutter与这两者的原理大不相同.
让我们来看看这三者的结构图吧.
可能有一些复杂, 咱大致解释一下.
React Native跟Xamarin都是基于mapping native代码来实现所谓的Native体验的框架, 只是RN基于JS引擎 + Bridge与native打交道, 并且在运行时进行绑定, 而Xamarin是基于微软的基于Linux的C#虚拟机mono + JNI与native进行通信.
这里Android与iOS还是有差别的, 如RN在iOS上JS引擎不支持JIT, 会一定程度影响效率, Xamarin在iOS上可以直接编译成iOS平台可以执行的程序, 所以在实际运行起来的性能是一样的, 唯一的差别就是微软得更快的支持API同步.
对于Flutter来说, 由于他的渲染引擎使用了Skia直绘, 加上基于C++的Dart引擎, 所以在不同平台上没有差别, 加之其实现了Android Material Design与iOS Cupertino两套UI组件, 所以即便是自绘组件, 看起来还是跟原生的一个样子.
通过对三种跨平台引擎的大致了解, 我们可以看出来, 他们都达到了一定程度的Native体验, 然则各自都有一定的性能损耗, 比如RN的JS引擎加载JS, 以及Bridge通信的损耗, Xamarin Mono虚拟机与Java通信的损耗, 以及Flutter Skia渲染与Native Android渲染的差异等.
Flutter笔记 如何启动一个appAndroid需要在Manfest里面指定带有MAIN action与LAUNCHER category的Activity声明, 而Flutter只需要一行.
void main() => runApp(MyApp());其中MyApp就是一个普通的Widgets(View).
View vs WidgetsFlutter没有View, 与之对应的是Widget, 并且分为StatelessWidgets与StatefulWidgets, 前者是个静态View, 后者是动态通过Data来更新的View.
Stateless
Text( 'I like Flutter!', );Stateful
class StatefulText extends StatefulWidget { @override State<StatefulWidget> createState() => _TextState(); } class _TextState extends State<StatefulText> { // Default placeholder text String textToShow = "I Like Flutter"; void _updateText() { setState(() { // update the text textToShow = "Flutter is Awesome!"; }); } @override Widget build(BuildContext context) { ...invoke _updateText } }实际上是因为StatefulWidgets通过调用State的setState方法来触发整个Widgets树的重绘, 并且在重绘之前会调用传进去的(){ ... }block.
怎么写Layout, XML到哪里去了.实际上Flutter没有xml了, 并且是通过Widgets的嵌套来实现一个布局的.
如:
Center是一个可以把子View放置在中央的容器.
Row对应的就是LinearLayout + Horizontal, Column对应的就是LinearLayout + Vertical, 他们都具备一个属性叫做crossAxisAlignment, 有点类似gravity, 来控制子View相对于父View的位置.
Expanded支持一个类似weight的属性, 叫flex.
Container是一个具有decoration属性的容器, 可以用来控制背景色, border, margin等等.
Stack有点像是一个特殊的RelatetiveLayout或者ConstraintLayout, children属性指定了它的子View, 第一个是Base View, alignment属性指定了后面的子View相对于BaseView的位置, 如alignment: const Alignment(0.6, 0.6)指定了位于BaseView右下角的位置.
ListTile是一个特殊的ListItem, 有三个属性, 分别是左边的Icon (leading), 文字 (title), 以及右边的Icon (trailing).
还有诸如ListView, GridView, Card等等比较熟悉的Widgets.
另外有一个类似于我们Activity的Widgets:
叫做MaterialApp, 可以指定theme, title, 以及子View home, 还有更重要的页面跳转routes.
MaterialApp( title: 'Welcome to Flutter', home: ..., routes: <String, WidgetBuilder> ..., theme: ThemeData( primaryColor: Colors.white ), )还有一个类似于Fragment的:
叫做Scaffold, 中文意思是脚手架, 它包含一个appBar (ActionBar)与一个body, appBar可以指定title与actions (类似于action button的点击事件).
Scaffold( appBar: AppBar( title: Text(widget.title), actions: <Widget>[...], ), body: ..., ) 如何从父View中Remove一个元素答案是没有... 因为在Flutter看来, Widgets的树结构是不可以被更改的, 但是如果想更改, 则是通过StatefulWidgets的方法, 通过setState来更改Data, 触发Widgets重绘, 从而替换掉之前的Widgets.
喜欢画Canvas的同学怎么办?