widget
相当于view
widget状态每改变一次,对应的状态树就会重新生成一次, widget的生命周期到状态发生改变就会销毁
view,修改一个视图并不会导致它重新创建实例,它作为一个可变对象,只会绘制一次,只有在发生 setNeedsDisplay() 调用之后才会发生重绘
和 UIView 不同,Flutter 的 widget 是很轻量的,一部分原因就是源于它的不可变特性。因为它并不是视图,也不直接绘制任何内容,而是作为对 UI 及其特性的一种描述,而被“注入”到视图中去
StatelessWidget:无状态view,相当于关闭用户交互的view
StatefulWidget:有状态的view,相当于打开用户交互的view
StatefulWidget 中有一个 State 对象,它用来存储一些状态的信息,并在整个生命周期内保持不变
如果不是自身直接响应修改(或别的输入),那么他的父容器也可以是无状态的
widget 是不可变的,只能重新生成,不想view等可以改变,没有add,remove方法,只能通过标示来判断是不是要生成view
floatingActionButton
onPressed
padding
动画
CurvedAnimation,它需要一个 Ticker,在屏幕刷新时发出信号量,并在运行时对每一帧都产生一个 0~1 的线性差值。然后你可以创建一个或多个 Animation,并把它们添加到控制器中。
绘制
Cavans , CustomPaint 和 CustomPainter
透明度
都需要封装 widget 到一个 Opacity widget 中
如何构建自定义 widget
如何构建一个初始方法中就包含文本标签的 CustomButton?需要创建一个合成一个 RaisedButton 和一个文本标签的 CustomButton,而不是继承 RaisedButton
如何在两个页面之间切换
构建由 route 名称组成的 Map;
直接跳转到一个 route。
如何跳转到其他应用
需要创建原生平台的整合层,或者使用已经存在的 插件,例如 url_launcher
如何退回到 iOS 原生的 viewcontroller
UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([viewController isKindOfClass:[UINavigationController class]]) {
[((UINavigationController*)viewController) popViewControllerAnimated:NO];
}
创建你自己的 平台通道 来调用对应的 iOS 代码
线程和异步
Dart 是单线程执行模型,支持 Isolate(一种在其他线程运行 Dart 代码的方法)、事件循环和异步编程。除非生成了 Isolate,否则所有 Dart 代码将永远在主 UI 线程运行,并由事件循环驱动。Flutter 中的事件循环类似于 iOS 中的 main loop—,也就是主线程上的 Looper
async/await
Isolates 是相互隔离的执行线程,并不和主线程共享内存。这意味着你不能够访问主线程的变量,也不能使用 setState() 来更新 UI。Isolates 正如起字面意思是不能共享内存(例如静态变量表)的
如何发起网络请求
增加依赖库
dependencies:
...
http: ^0.11.3+16
loadData() async {
String dataURL = "https://jsonplaceholder.typicode.com/posts";
http.Response response = await http.get(dataURL);
setState(() {
widgets = jsonDecode(response.body);
});
}
展示耗时任务的进度
ProgressIndicator
当 showLoadingDialog() 是 true 时(当 widgets.length == 0),渲染 ProgressIndicator。否则,使用网络请求返回的数据渲染 ListView
工程结构,本地化,依赖和资源
如何在 Flutter 中引入图片资源?如何处理多分辨率
文件倒入
assets:
- my-assets/data.json
使用
('my-assets/data.json');
图片
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
倒入
assets:
- images/my_icon.png
使用
images/a_dot_burr.jpeg
字符串存储在哪里?如何处理本地化?
默认情况下,Flutter 只支持美式英语的本地化字符串。如果你需要添加其他语言支持,请引入 flutter_localizations
库。同时你可能还需要添加 intl
库来使用 i10n 机制
dependencies:
# ...
flutter_localizations:
sdk: flutter
intl: "^0.15.6"
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
localizationsDelegates: [
// Add app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('he', 'IL'), // Hebrew
// ... other locales the app supports
],
// ...
)
CocoaPods 相当于 Flutter 中的什么?如何添加依赖
pods增加原生依赖
yaml增加flutter依赖
ViewControllers
ViewControllers 相当于 Flutter 中的什么?
Widgets
使用 Naivgator 在不同的 Route 之间切换,而不同的路由则代表了不同的屏幕或页面,或是不同的状态,也可能是渲染相同的数据
如何监听 iOS 中的生命周期?
通过在 WidgetsBinding 的 observer 中挂钩子,也可以通过监听 didChangeAppLifecycleState() 事件,来实现相应的功能
可监听的生命周期事件有:
inactive
应用当前处于不活跃状态,不接收用户输入事件。这个事件只在 iOS 上有效,Android 中没有类似的状态。
paused
应用当前处于用户不可见状态,不接收用户输入事件,但仍在后台运行。
resumed
应用可见,也响应用户输入。
suspending
应用被挂起,在 iOS 平台没有这一事件。
布局
UITableView 和 UICollectionView
ListView
如何确定列表中被点击的元素
通过 widget 传递进来的 touch 响应处理来实现
如何动态更新 ListView
在 Flutter 里,如果你在 setState() 中更新了 widget 列表,你会发现展示的数据并不会立刻更新。这是因为当 setState() 被调用时,Flutter 的渲染引擎回去检索 widget 树是否有改变。当它获取到 ListView,会进行 == 判断,然后发现两个 ListView 是相等的。没发现有改变,所以也就不会进行更新。
一个更新 ListView 的简单方法就是,在 setState() 创建一个新的 List,然后拷贝旧列表中的所有数据到新列表。这样虽然简单,但是像下面示例一样数据量很大时,并不推荐这样做
一个推荐的、高效且有效的方法就是使用 ListView.Builder 来构建列表。当你的数据量很大,且需要构建动态列表时,这个方法会非常好用。
和创建 ListView 不同,创建 ListView.Builder 需要两个关键参数:初始化列表长度和 ItemBuilder 函数。
ItemBuilder 函数和 iOS 里 tableView 和 collectionView 的 cellForItemAt 方法类似,它接收位置参数,然后返回想要在该位置渲染的 cell。
最后,也是最重要的,注意 onTap() 方法并没有重新创建列表,而是使用 .add 方法进行添加
ScrollView 相当于 Flutter 中的什么
ListView
手势检测与 touch 事件处理
如何给 Flutter 的 widget 添加点击事件
如果 widget 本身支持事件检测,则直接传递处理函数给它
如果 widget 本身不支持事件检测,那么把它封装到一个 GestureDetector 中,并给它的 onTap 参数传递一个函数
如何处理 widget 的其他手势
单击事件
onTapDown
用户在特定区域发生点触屏幕的一个即时操作。
onTapUp
用户在特定区域发生触摸抬起的一个即时操作。
onTap
从点触屏幕之后到触摸抬起之间的单击操作。
onTapCancel
用户在之前触发了 onTapDown 时间,但未触发 tap 事件。
双击事件
onDoubleTap
用户在同一位置发生快速点击屏幕两次的操作。
长按事件
onLongPress
用户在同一位置长时间触摸屏幕的操作。
垂直拖动事件
onVerticalDragStart
用户手指接触屏幕,并且将要进行垂直移动事件。
onVerticalDragUpdate
用户手指接触屏幕,已经开始垂直移动,且会持续进行移动。
onVerticalDragEnd
用户之前手指接触了屏幕并发生了垂直移动操作,并且停止接触前还在以一定的速率移动。
水平拖动事件
onHorizontalDragStart
用户手指接触屏幕,并且将要进行水平移动事件。
onHorizontalDragUpdate
用户手指接触屏幕,已经开始水平移动,且会持续进行移动。
onHorizontalDragEnd
用户之前手指接触了屏幕并发生了水平移动操作,并且停止接触前还在以一定的速率移动。
主题和文字
如何设置应用主题
ThemeData
如何给 Text widget 设置自定义字体?
fonts:
- family: MyCustomFont
fonts:
- asset: fonts/MyCustomFont.ttf
- style: italic
TextStyle(fontFamily: 'MyCustomFont'),
如何设置 Text widget 的样式:Style
color
decoration
decorationColor
decorationStyle
fontFamily
fontSize
fontStyle
fontWeight
hashCode
height
inherit
letterSpacing
textBaseline
wordSpacing
表单输入
通过特定的 widget 来实现。如果你有一个 TextField
或者 TextFormField
,你可以通过 TextEditingController
来获取用户的输入
TextField 中的 placeholder 相当于什么
InputDecoration
如何展示验证错误信息
InputDecoration
和硬件、第三方服务以及系统平台交互
如何与系统平台以及平台原生代码进行交互
platform channels
如何访问 GPS 传感器
如何访问相机
如何使用 Facebook 登录
如何集成 Firebase 的功能
- 搭配
firebase_admob
插件来使用 Firebase AdMob - 搭配
firebase_analytics
插件来使用 Firebase Analytics - 搭配
firebase_auth
插件来使用 Firebase Auth - 搭配
firebase_core
插件来使用 Firebase 核心库 - 搭配
firebase_database
插件来使用 Firebase RTDB - 搭配
firebase_storage
插件来使用 Firebase Cloud Storage - 搭配
firebase_messaging
插件来使用 Firebase Messaging (FCM) - 搭配
cloud_firestore
插件来使用 Firebase Cloud Firestore
如何构建自己的插件
根据 developing packages and plugins 构建自己的插件
数据库和本地存储
Flutter 中如何访问 UserDefaults?
CoreData 相当于 Flutter 中的什么?
Debugging
通知
如何设置推送通知
firebase_messaging