零、项目结构、资源、国际化等
1、资源
Flutter项目的资源放在iOS的
Images.xcasset
Resources that are placed in the Images.xcasset folder on iOS, are placed in an assets folder for Flutter.
Flutter中的资源文件需要在
pubspec.yaml
声明才能用。 —— 这点很繁琐Flutter多分辨率的支持
// 资源文件下按目录放置
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
// yaml文件中声明,然后自动匹配
assets:
- images/my_icon.png
2、国际化
- Flutter默认不支持国际化(iOS通过Localizable.strings文件支持。)
- Flutter通过
flutter_localizations
和intl
包 支持国际化。
3、依赖包管理
iOS使用Cocoapod,Flutter使用pubspec.yaml
进行管理。
一、View
1、UIView --> Widget
iOS中的UIView,可以等价于Flutter的Widget。
Widget 是不可变的;不管是widgets或者它们状态的改变,Flutter框架都会创建新的widget-tree。
Whenever widgets or their state change, Flutter’s framework creates a new tree of widget instances.
iOS中的UIView 是可变的并只会创建一次,除非setNeedsDisplay()调用后才会重构。Widget的更新:只能通过 State对象 默默更新(manipulate)widget-tree。
Flutter将Widget分为两大类,StatelessWidget 和 StatefulWidget(内部有State对象用来存储data和更新widget)。透明属性差异?
iOS中直接使用属性.opacity、.alpha
直接设置。而Flutter中,需要将widget包裹在OpacityWidget
里面。
2、布局Layout的差异
- Flutter中布局也是一种Widget,同样存在与widget-tree中。
Layout widgets
3、如何添加和删除widget?
iOS可以通过方法addSubview()、removeFromSuperview()
直接添加和删除 view。
- Flutter无法直接操作widget-tree,只能在ParentWidget构建中,通过 代码变量控制 返回不同的widgets。
Instead, you can pass a function to the parent that returns a widget, and control that child’s creation with a boolean flag.
3、动画构建差异?
iOS直接通过调用withDuration:animations:
方法,直接创建动画效果。
Flutter中,通过
animation-library
直接包裹widgets,依次创建动画。
In Flutter, use the animation library to wrap widgets inside an animated widget.
例如,AnimationController、CurvedAnimation 、FadeTransition等类。详见
Animation & Motion widgets
Animations tutorial
Animations overview.
4、View的重绘
iOS依赖于CoreGraphics
框架进行重绘。
- Flutter 依赖于
Canvas
框架的APIs,一般是依赖于两个类CustomPaint
andCustomPainter
。
5、如何自定义Widget
iOS一般采用继承UIView重写View,然后组合方式添加Subviews;Flutter推荐采用组合的方式进行自定义widget。
二、导航
1、导航管理
iOS使用UINavigationController
进行导航堆栈的管理。
- Flutter中使用
Navigator
和Routes
进行管理;其中Routes
相当于页面的页面(screen&page),可以理解为iOS的UIViewController
,而Navigator
是负责管理Routes
,可以理解为iOS的UINavigationController
;
2、两个App间如何进行跳转?
- iOS通过url-schema、统一链接方式。
- To implement this functionality in Flutter, create a native platform integration, or use an existing plugin, such as
url_launcher
.
三、多线程与异步
1、Flutter的单线程模式
iOS提供多种多线程技术,包括Operation、GCD、Thread、Perform等等。
Flutter中一般默认在主线程
main-ui-thread
中执行;也提供isolate
的支持多线程概念,其有独立的内存地址和event-loops。Flutter推荐使用Flutter/Stream 或 async/wait 实现异步,不卡主线程。
Flutter的单线程模型,让你不用考虑数据同步等线程问题;这一点和 Node.js 很像。
Since Flutter is single threaded and runs an event loop (like Node.js), you don’t have to worry about thread management or spawning background threads.
2、Flutter支持多线程模式,isolate
其有独立的内存堆,这一点和Thread不同,可又不是进程。
In Flutter, use Isolates to take advantage of multiple CPU cores to do long-running or computationally intensive tasks.Isolates are separate execution threads that do not share any memory with the main execution memory heap.
isolate之间无法直接访问变量,只能通过消息机制,即port相关接口。
This means you can’t access variables from the main thread, or update your UI by calling setState(). Isolates are true to their name, and cannot share memory (in the form of static fields, for example).
3、http请求
使用http package.
import 'package:http/http.dart'
四、UIViewController
- Flutter的Widget 也担当 iOS的
UIViewController
的职责。
1、生命周期的监听
iOS通过UIViewController 和 AppDelegate 的回调函数或Notification,监听应用和页面的生命周期。
Flutter通过
WidgetsBinding
和didChangeAppLifecycleState()
监听
AppLifecycleState
documentation.监听的事件
1、非活跃,inactive
The application is in an inactive state and is not receiving user input. This event only works on iOS, as there is no equivalent event on Android.
2、暂停,paused
The application is not currently visible to the user, is not responding to user input, but is running in the background.
3、唤醒,resumed
The application is visible and responding to user input.
4、中止,suspending
The application is suspended momentarily. The iOS platform has no equivalent event.
五、TableView 和 ScrollView
1、UITableView/UICollectionView/ScrollView
--> ListView
- Cell的点击:Flutter通过 包裹手势或者点击Widget 给予支持。—— 这点iOS通过回调方式,高效的多。
- 列表的动态更新
Flutter中,推荐使用ListView.Builder
更新列表数据;或者在setState()
方法内,重新生成新List,否则不会更新。(这是因为setState()
的机制是通过==
比较数据是否变化,list变量不变,因此widget不更新。)
六、手势和点击事件的监听, Gesture detection and touch event handling
1、Flutter提供两种方法
- widget支持,提供事件回调。如
ElevatedButton
- 使用
GestureRecognizer
进行包裹widget。
2、GestureDetector 支持的手势
Tapping
onTapDown
A pointer that might cause a tap has contacted the screen at a particular location.
onTapUp
A pointer that triggers a tap has stopped contacting the screen at a particular location.
onTap
A tap has occurred.
onTapCancel
The pointer that previously triggered the onTapDown won’t cause a tap.Double tapping
onDoubleTap
The user tapped the screen at the same location twice in quick succession.
Long pressingonLongPress
A pointer has remained in contact with the screen at the same location for a long period of time.
Vertical draggingonVerticalDragStart
A pointer has contacted the screen and might begin to move vertically.
onVerticalDragUpdate
A pointer in contact with the screen has moved further in the vertical direction.
onVerticalDragEnd
A pointer that was previously in contact with the screen and moving vertically is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
Horizontal draggingonHorizontalDragStart
A pointer has contacted the screen and might begin to move horizontally.
onHorizontalDragUpdate
A pointer in contact with the screen has moved further in the horizontal direction.
onHorizontalDragEnd
A pointer that was previously in contact with the screen and moving horizontally is no longer in contact with the screen.
七、风格
- Flutter默认支持android-Material,
WidgetsApp()
;或者iOS-Cupertino,CupertinoApp()
。 - 支持自定义字体,在
pubspec.yaml
配置。
八、硬件交互
Interacting with hardware, third party services and the platform
1、原生代码交互,platform channel
- PlatformChannel 是一套异步的消息机制。
2、支持访问原生的相机、GPS等功能。
3、自定义插件
九、持久化
UserDefault
Shared Preferences plugin数据库(Flutter支持SQLite)
SQFlite通知机制
firebase_messaging