入门: 在macOS上搭建Flutter开发环境
Flutter 的安装
课程安排
Flutter 简介 :跨平台技术、环境搭建、应用项目
Dart 简介 :运行环境、基本语法、高级语法
项目介绍 :界面介绍、网络介绍、Git和文档使用
功能开发 :框架准备、组件使用、应用开发
高级应用 :混合应用、页面栈管理、Flutter For Web
移动端技术
跨平台:write once ,run anywhere
2014年 - Web页面:(最成功的跨平台)H5+CSS+Js
2015年 - React Native:(Facebook 推出的)JS -> iOS + Android
2016年 - WeeX:(阿里巴巴)JS -> iOS + Android + Web
2017年 - Flutter:(Google)Dart -> iOS + Android
认识 Flutter
1、快速开发(毫秒级的热重载,快速开发刷新)
2、富有表现力和灵活的UI
3、原生性能
Flutter底层使用的是Dart语言
一、Dart 语言
课程安排:
- 基本运行环境
- 变量与类型
- 控制流语句
- 函数
- 类与对象
- 继承与多态
- 抽象类与接口
- 静态与权限
- 异步
- 官方文档
2、变量和类型
· 变量
· 类型 变量名 = 值
· 如果一个变量在定义之后没有赋值 -> null
· 类型
· 基本类型:bool、num(int & double)、String、enum
· 泛型:List、Map
int a;
String b;
List<int> listA = [1,2,3];
List<String> listB = ['a','b','c'];
enum Colors {Red,Blue,Green}
void main() {
Colors c = Colors.Red;
if (c == Colors.Red) {
print(true);
}
}
· var
· 接受任何类型
· 一旦赋值,无法改变类型
因为 Dart 语言是个 强类型语言 ,任何变量都有自己确定的类型
· dynamic & Object
dynamic | Object | |
---|---|---|
不同点 | 编译器会提供所有可能的组合 | 只能使用Object属性和方法 |
相同点 | 可以在后期改变赋值类型 | 可以在后期改变赋值类型 |
3、控制流语句
· 条件判断
· if 与其他语言差别不大
· Debug 模式下接受bool类型,Release接受任何类型
// 判断是否为偶数
bool isEven(int n) {
if (n.isEven) {
return true;
} else {
return false;
}
}
· switch 语句
· 非空case 在执行完之后必须以break、return、continue 的方式结束
· 空case 继续执行
· 循环语句
· for 与其他语言差别不大
· while 是个简化版的for
· do-while 先执行一次,再判断
List<int> listA = [1,2,3];
bool isPositive() {
for (int n in listA) {
if (n > 0) {
return true;
}
}
for (int i = 0; i < listA.length; i++){
if (listA[i] > 0) {
return true;
}
}
int n = 0;
while (n < listA.length) {
if (listA[n] > 0) {
return true;
}
n++;
}
return false;
}
· 跳转语句
· break 跳出整个循环
· continue 跳出当前循环
4、函数
· 声明
· 没有显示声明返回值类型默认当做dynamic
· 函数返回值没有推断类型
· 返回值可以用 “ => ”简写
void main() {
int power = calPowera(5);
print(power);
}
int calPower(int a) {
return a * a;
}
int calPowera(int a) => a * a;
· 函数变量
· 作为参数
· 参数传递
· 作为参数
int calPower(int n) {
return n * n;
}
void printPower(var power) {
print(power);
}
void main(){
printPower(calPower(8));
}
· 可选位置参数
· 可以用“[ ]”来标记可选的参数位置
· 可选命名参数
· 可以用“{ }”来标记可选的命名参数
void main() {
int m1 = calA(4);
int m2 = calA(5,6);
int m3 = calB(4,b:6);
}
int calA(int a,[int b]) {
if (b != null) {
return a * b;
} else {
return a * a;
}
}
int calB(int a,{int b}) {
if (b != null) {
return a * b;
} else {
return a * a;
}
}
可以看出,m2 位置参数可以不加b这个参数名,m3中需要添加b这个参数名
5、类和对象
· 定义
· class
· 构造函数
· 与类同名
· 没有显示提供、等价于提供了一个空的构造函数
· 没有析构函数 因为自带垃圾回收
· 简写
· 命名构造函数
· 更加方便
· 重定向构造函数
· 调用另一个构造函数
class Person {
int age;
String name;
// 构造函数
Person(int age, String name) {
this.age = age;
this.name = name;
}
// 简写
Person(this.age, this.name);
// 命名构造函数
// 类型.自定义名字(参数)
Person.fromList(List<dynamic> list) {
age = list[0];
name = list[1];
}
// 重定向构造函数
// 类型.自定义名字(参数):this(属性)
Person.default(int age,String name):this(age,name);
}
void main() {
Person a = new Person(20, 'a');
Person b = new Person.fromList([30,'a']]);
Person c = new Person.default(30, 'a');
}
6、继承与多态
· 继承
· 只能单继承,继承一个基类:extends
· 调用基类方法:super
· 多态
· 没有多大差别
class Person {
int age;
String name;
Person(int age, String name) {
this.age = age;
this.name = name;
}
// 简写
Person(this.age, this.name);
// 命名构造函数
// 类型.自定义名字(参数)
Person.fromList(List<dynamic> list) {
age = list[0];
name = list[1];
}
// 重定向构造函数
// 类型.自定义名字(参数):this(属性)
Person.default(int age,String name):this(age,name);
int howOld() {
return age;
}
}
class Male extends Person {
// 构造函数 调用父类构造函数
Male(int age,String name):super(age,name);
@override
int howOld() {
return age + 1;
}
}
void main() {
Person a = new Person(20,'a');
print(a.howOld());//20
Male b = new Male(20, 'a');
print(b.howOld());//21
}
7、抽象类与接口
· 抽象类
· 关键字:abstract
· 不能实例化
· 抽象函数:声明但不实现
· 派生类必须重写抽象类所有的抽象函数
· 接口
· 关键字:implements
· Dart每个类都是接口
· 必须实现除构造函数外的所有成员函数
// 定义一个抽象类
abstract class Person {
// 抽象函数:声明但是没有实现
String getName();
int howOld() {
return 20;
}
}
// 派生类
class Male extends Person {
// 必须全部重新所有的抽象函数
String getName() {
return 'a';
}
}
void mains() {
// Abstract classes can't be instantiated. 无法实例化抽象类。
// Try creating an instance of a subtype.dar 尝试创建一个子类的实例
Person a = new Person();
Male b = new Male();
print(b.getName());
}
// 定义一个 AA 实现 Male 函数
class AA implements Male {
// 必须全部实现
@override
int howOld() {
return 20;
}
// Missing concrete implementation of 'Male.getName'. 缺少getName具体实现方法
// @override
// String getName() {
// return 'AA';
// }
}
所以如果想复用某个函数中的某段代码的话,就去继承它。Male想要复用getName就继承Person,如果想把Male当成一个接口就去实现它
8、静态与权限
· 静态和非静态的成员,成员函数
非静态 | 静态 | |
---|---|---|
修饰 | 无 | static |
属于 | 对象 | 类 |
访问 | 成员、静态成员、成员函数、静态成员函数 | 只能访问静态成员和静态成员函数 |
· 权限
· 无关键字
· 使用符号 “” 表示权限,使用“”开始的成员变量、类表示“包”之内都可以访问,“包”之外不能访问;无“_” 包内外皆可访问
· 不存在针对类的访问权限、只有针对包(package)的
9、异步支持
· 异步运算(async)-> 延迟队列(await)-> 等待结果(Future)
· await 必须在 async 之后
void main() {
String data = '这是个data';
getData(data);
}
getData(String data) async {
print(data); // 这是个data
data = await Future.delayed(Duration(seconds: 2),(){
return '这是打印网络请求';
});
print(data); // 这是打印网络数据
}
· Future
· 表示异步操作的最终完成(或失败)
· 只会有一个结果
· 返回值仍然是Future类型
· Future.then
· 成功 使用 return 返回
· Future.catchError
· 因为返回的是Future类型,所以直接在后面添加.catchError
· Future.then 可选参数
· Future.then 也有一个可选参数,跟 Future.catchError效果是一样的
· Future.whenComplete
· 表示无论失败或者成功,都会调用
· Future.wait
· 等待多个异步任务执行结束后再执行
· 接受一个Future数组参数
void main() {
// Future<String> future = getData();
// future.then((value) {
// print(value);//flutter: 这是延迟2秒钟之后执行结果
// })
// .catchError((e) {
// print(e); // Assertion failed
// });
Future<String> future = getData();
future.then((value) {
print(value);//flutter: 这是延迟2秒钟之后执行结果
},onError: (e) {
print(e); // Assertion failed
});
}
Future<String> getData() async {
return await Future.delayed(Duration(seconds: 2), () {
throw AssertionError("Error");
// return "这是延迟2秒钟之后执行结果";
});
Future.wait([
Future.delayed(Duration(seconds: 2), () {
return "第一步";
}),
Future.delayed(Duration(seconds: 2), () {
return "第二步";
})
]).then((value) {
print(value[0] + "," + value[1]); // 第一步,第二步
},onError: (e) {
print(e);
});
}
10、文档学习
· 语法概览
· 语法概览:https://dart.dev/guides/language/language-tour
· 简书博客:https://www.jianshu.com/p/9e5f4c81cc7d
网友评论