当前位置: 首页>大数据>正文

初识Flutter

Flutter是谷歌发布的一个UI工具包,它能通过统一的编码方式,编译出原生的移动端,网页端,桌面端的应用。

Dart是用来编写Flutter应用程序的语言,它是一门类型安全的语言,它使用静态类型检查来确保变量的值始终与变量的静态类型相匹配。尽管类型是强制性的,但由于 Dart 支持类型推断,类型注释仍是可选的。Dart还提供空值安全,意思是当声明值可以为空的情况下,值才可以为空。当确定变量不为空时,该变量永远不可为空。这两点与Swift的语法一样。

在开发过程中,由于Dart VM提供了一个实时编译器(JIT),所以应用可以热重载,可以加快开发效率。当将应用部署到生产环境时,Dart AOT编译器提供了原生的ARM或x64机器码的编译,以便应用程序稳定快速的启动。

做为一名iOS开发者接触Flutter后的一些理解:

在Flutter中,UI的编程方式是声明式编程,不同于OC和Swift的命令式编程,和SwiftUI是一样的。iOS中的UIView可以理解为Flutter中的Widget,虽然有着相当一部分的不同。Widget有着不同的声明周期,整个声明周期内它是不可变的,只能存活到被修改的时候,一旦Widget实例或者它的状态发生了改变,Flutter框架就会创建一个新的Widget实例。而在iOS中,修改一个视图并不会重新创建实例,它作为可变对象,只绘制一次,只有发生setNeedsDisplay()调用之后才发生重绘。Widget是轻量级的,它不是视图,而是视图的描述。

Flutter包含了Material Components库,它是一个通用的UI库,支持全平台的UI设计。它也提供了专门给iOS开发使用的Cupertino widgets来构造类似苹果界面的组件。

如何更新Widget

在Flutter中引入了Stateful widget和Stateless widget概念,当我们声明的UI是静态的以后不会有变化时,可以使用StatelessWidget。但是如果想要根据 HTTP 请求的返回结果动态的修改 UI,那么应该使用?StatefulWidget。在 HTTP 请求结束后,通知 Flutter 更新这个 widget 的?State,然后 UI 就会得到更新。

StatefulWidget?和?StatelessWidget?最重要的区别就是,?StatefulWidget?中有一个?State?对象,它用来存储一些状态的信息,并在整个生命周期内保持不变。

当一个StatelessWidget想要改变它的UI时,只需要把它放进StatefulWidget中,并在需要时更新State就可以了。

widget布局

Flutter布局的核心机制是widgets。在Flutter中,几乎所有东西都是widget,甚至是布局。我们可以通过这个网站来学习widget布局。

增加或者移除一个组件

在iOS中,可以通过调用父视图的addSubview()或者removeFromSuperview()来添加或者移除视图。在 Flutter 中,因为 widget 是不可变的,所以没有提供直接同?addSubview()?作用相同的方法。但是你可以通过向父视图传递一个返回值是 widget 的方法,并通过一个 boolean flag 来控制子视图的存在。

添加动画

在 Flutter 里,通过使用动画库将 widget 封装到 animated widget 中来实现带动画效果。

在 Flutter 里,使用?AnimationController,它是一个可以暂停、查找、停止和反转动画的?Animation<double>?类型。它需要一个?Ticker,在屏幕刷新时发出信号量,并在运行时对每一帧都产生一个 0~1 的线性差值。然后你可以创建一个或多个?Animation,并把它们添加到控制器中。

比如,你可以使用?CurvedAnimation?来实现一个曲线翻页动画。这种情况下,控制器就是动画进度的主要数据源,而?CurvedAnimation?计算曲线并替换控制器的默认线性运动,和 widget 一样,在 Flutter 里动画也可以复合嵌套。

当构建一个 widget 树时,可以将?Animation?赋值给 widget 用户表现动画能力的属性,比如?FadeTransition?的 opacity 属性,然后告诉控制器启动动画。

在两个页面之间切换

Flutter中使用Navigator和Routes来实现页面之间的切换。一个Route是应用中屏幕或者页面的抽象概念,而一个?Navigator?是管多个?Route?的?widget。也可以理解把?Route?理解为?UIViewController。而?Navigator?的工作方式和 iOS 里的?UINavigationController?类似,当你想要进入或退出一个新页面的时候,它也可以进行?push()?和?pop()?操作。

编写异步代码

Dart 是单线程执行模型,支持?Isolate(一种在其他线程运行 Dart 代码的方法)、事件循环和异步编程。除非生成了?Isolate,否则所有 Dart 代码将永远在主 UI 线程运行,并由事件循环驱动。Flutter 中的事件循环类似于 iOS 中的 main loop—,也就是主线程上的?Looper。

Dart 的单线程模型并不意味着你需要以阻塞 UI 的形式来执行代码,相反,你更应该使用 Dart 语言提供的异步功能,比如使用?async/await?来实现异步操作。

例如,你可以使用?async/await?来执行网络代码以避免 UI 挂起,让 Dart 来完成这个繁重的任务。

让你的任务在后台线程执行

由于 Flutter 是单线程模型,而且执行着一个 event loop(就像 Node.js),你不需要为线程管理或是开启后台线程操心。如果你在处理 I/O 操作,例如磁盘访问或网络请求,那么你安全地使用?async/await?就可以了。但是,如果你需要大量的计算来让 CPU 保持忙碌状态,你需要使用?Isolate?来防治阻塞 event loop。

发起网络请求

在 Flutter 里,想要构造网络请求十分简单,直接使用?http?库?即可。它把你可能要实现的网络操作进行了抽象封装,让处理网络请求变得十分简单。

在 Flutter 中引入图片资源

在Flutter中,图片资源被放置在assets文件夹中。对于图片,Flutter 和 iOS 一样遵循了一个简单的基于屏幕密度的格式。 Image assets 可能是?1.0x,2.0x,3.0x?或者其他任意的倍数。而?devicePixelRatio?则表达了物理分辨率到逻辑分辨率的对照比例。

Assets 可以放在任何属性的文件夹中—Flutter 没有任何预置的文件结构。你需要在?pubspec.yaml?中声明 assets (包括路径),然后 Flutter 将会识别它们。

例如,要添加一个名为?my_icon.png?的图片到你的 Flutter 工程中,你可以把它存储在?images?文件夹下。把基础的图片(一倍图)放到?images?文件夹下,然后把其他倍数的图片放置到对应的比例下的子文件夹中。

images/my_icon.png // Base: 1.0x image

images/2.0x/my_icon.png? // 2.0x image

images/3.0x/my_icon.png? // 3.0x image

接着,在?pubspec.yaml?文件中声明这些图片:

assets:

-images/my_icon.png

接下来便可以在代码中访问图片了

AssetImage("images/a_dot_burr.jpeg");

Image.asset("images/my_image.png");

添加依赖

总而言之,在 Flutter 中使用?pubspec.yaml?来声明外部依赖。你可以通过?pub.dev?来查找一些优秀的 Flutter 第三方包。

监听 iOS 中的生命周期

在Flutter中可以通过在?WidgetsBinding?的 observer 中挂钩子,也可以通过监听?didChangeAppLifecycleState()?事件,来实现相应的功能。

可监听的生命周期事件有:

inactive

应用当前处于不活跃状态,不接收用户输入事件。这个事件只在 iOS 上有效,Android 中没有类似的状态。

paused

应用当前处于用户不可见状态,不接收用户输入事件,但仍在后台运行。

resumed

应用可见,也响应用户输入。

suspending

应用被挂起,在 iOS 平台没有这一事件。

ListView

它和 iOS 中的?ScrollView?以及?TableView?表现一致,也可以给它的子 widget 做垂直排版。

手势检测与 touch 事件处理

在Flutter中,如果widget本身支持事件监测,则直接传递处理函数给它。如果widget本身不支持事件检测,那么把它封装到一个GestureDetector中。

GestureDetector还可以监听更多的手势,例如:

单击事件

onTapDown

用户在特定区域发生点触屏幕的一个即时操作。

onTapUp

用户在特定区域发生触摸抬起的一个即时操作。

onTap

从点触屏幕之后到触摸抬起之间的单击操作。

onTapCancel

用户在之前触发了?onTapDown?时间,但未触发 tap 事件。

双击事件

onDoubleTap

用户在同一位置发生快速点击屏幕两次的操作。

长按事件

onLongPress

用户在同一位置长时间触摸屏幕的操作。

垂直拖动事件

onVerticalDragStart

用户手指接触屏幕,并且将要进行垂直移动事件。

onVerticalDragUpdate

用户手指接触屏幕,已经开始垂直移动,且会持续进行移动。

onVerticalDragEnd

用户之前手指接触了屏幕并发生了垂直移动操作,并且停止接触前还在以一定的速率移动。

水平拖动事件

onHorizontalDragStart

用户手指接触屏幕,并且将要进行水平移动事件。

onHorizontalDragUpdate

用户手指接触屏幕,已经开始水平移动,且会持续进行移动。

onHorizontalDragEnd

用户之前手指接触了屏幕并发生了水平移动操作,并且停止接触前还在以一定的速率移动。

设置应用主题

如果想定义所有子组件颜色和样式,可以直接传递?ThemeData?对象给?MaterialApp?widget。

设置?Text?widget 的样式

除了字体以外,你也可以自定义?Text?widget 的其他样式。Text?widget 接收一个?TextStyle?对象的参数,可以指定很多参数,例如:

color

decoration

decorationColor

decorationStyle

fontFamily

fontSize

fontStyle

fontWeight

hashCode

height

inherit

letterSpacing

textBaseline

wordSpacing

表单输入

和 Flutter 的其他部分一样,表单处理要通过特定的 widget 来实现。如果你有一个?TextField?或者?TextFormField,你可以通过?TextEditingController?来获取用户的输入。

在 Flutter 里,通过向?Text?widget 传递一个?InputDecoration?对象,你可以轻易的显示placeholder。

硬件交互

使用?geolocator?插件,访问GPS传感器。image_picker?是常用的访问相机的插件。登录 Facebook 可以使用?flutter_facebook_login?插件。

数据库和本地存储

在 Flutter 里,可以使用?Shared Preferences 插件?来实现类似iOS的UserDefaults相同的功能。可以使用?SQFlite?插件来实现类似CoreData这个功能。

设置推送通知

在 iOS 里,你需要向开发者中心注册来允许推送通知。

在 Flutter 里,使用?firebase_messaging?插件来实现这个功能。


https://www.xamrdz.com/bigdata/7an1993852.html

相关文章: