最近一直在跟着学习Flutter,当然首先还是得学习下dart语法,不得不说dart真的是一种比较适合人类的编程语言,它结合了多种编程语言的特性于一身,但是也有一个麻烦,就是维护起来比较花费时间,当接手上一位的项目时候,可能就难以入手了。除了这个其它就比较方便了。
下面整理下学习过程,需要学习的东西,具体详细可以看提供的链接,也可以网上搜索,一大把,重复的东西就不打算写了。
首先得去下载安装包,这个开发时候会使用,点击下载,当然有时候网络问题,这个我已经下载好了放在百度云盘了,
链接:https://pan.baidu.com/s/1dBiwOW4PoSVpUAofXPydQw
提取码:wgpb
避免了下载不到的情况,下载好了别忘记配环境变量
写dart代码的有多种ide,是可以供选择的,比如Android Studio,或者Visual Studio Code等,只要安装对应插件就可以了,我用的是Android Studio,安装了两个插件,Flutter,支持开发Flutter工作流,Dart插件,提供语法分析 (输入代码时进行验证、代码补全等)。
var:如果没有初始值,可以变成任何类型
dynamic:动态任意类型,编译阶段不检查类型
Object:动态任意类型,编译阶段检查检查类型
区别:
唯一区别 var 如果有初始值,类型被锁定
const 修饰的变量,创建后不能更改值 ,是编译时常量
final修饰的变量,只能设置一次值,不能更改
程序运行时,需要传值时,使用final
const在运行时无法访问任何内容
注意:
int和double是num的子类
可在函数内定义,dart中是Function类型的对象,定义函数时可省略类型,支持缩写语法(=>),函数如果需要返回值而没有返回的话,会默认会返回一个null,这个需要注意
1.可选命名参数:使用 {param1, param2, …} 的形式来指定命名参数
2.可选位置位置:把可选参数放到 [] 中,必填参数要放在可选参数前面
3.默认参数值:可选命名参数默认值(默认值必须是编译时常量),可以使用等号‘=’或冒号’:‘(建议使用等号),可使用list或map作为默认值,但必须是const
可赋值给变量,通过变量调用;可在其它函数中直接调用或传递给其它函数
闭包定义
typedef给函数起一个别名,使用比较方便。例如定义一个方法的回调,直接使用别名定义。没返回值,则只要参数匹配就行了,如果定义了返回值,则返回值不一样会报错。
// 1. if else
// 2. for,forEach,for-in
// 3. while, do while
// 4. break, continue
/ /5. switch case
异常捕获和抛出,自定义异常,dart代码可以抛出任何非nulll对象为异常,不仅仅是实现了Exception或者Error的对象
//dart建议写法
class Point {
num x;
num y;
Point(this.x, this.y);
}
//使用命名构造函数可以为一个类实现多个构造函数, 或者使用命名构造函数来更清晰的表明你的意图。
class Point {
num x;
num y;
Point(this.x, this.y);
//命名构造函数
Point.fromJson(Map json) {
x = json['x'];
y = json['y'];
}
}
//一个重定向构造函数是没有代码的,在构造函数声明后,使用 冒号调用其他构造函数。
class Point {
num x;
num y;
Point(this.x, this.y);
//重定向构造函数,使用冒号调用其他构造函数
Point.alongXAxis(num x) : this(x, 0);
}
//在构造函数体执行之前可以初始化实例参数。 使用逗号分隔初始化表达式。
//初始化列表非常适合用来设置 final 变量的值。
import 'dart:math';
class Point {
//final变量不能被修改,必须被构造函数初始化
final num x;
final num y;
final num distanceFromOrigin;
//初始化列表
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
//超类命名构造函数不会传递,如果希望使用超类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数。
//如果超类没有默认构造函数, 则你需要手动的调用超类的其他构造函数。
//调用超类构造函数的参数无法访问 this。
//在构造函数的初始化列表中使用 super(),需要把它放到最后。
class Child extends Parent {
int x;
int y;
//若超类没有默认构造函数, 需要手动调用超类其他构造函数
Child(x, y) : super.fromJson(x, y) {
//调用父类构造函数的参数无法访问 this
print('子类构造函数');
}
//在构造函数的初始化列表中使用super(),需要把它放到最后
Child.fromJson(x, y)
: x = x,
y = y,
super.fromJson(x, y) {
print('子类命名构造函数');
}
}
//定义const构造函数要确保所有实例变量都是final。
//const关键字放在构造函数名称之前。
class Point2 {
//定义const构造函数要确保所有实例变量都是final
final num x;
final num y;
static final Point2 origin = const Point2(0, 0);
//const关键字放在构造函数名称之前,且不能有函数体
const Point2(this.x, this.y);
}
//工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象。
//如果一个构造函数并不总是返回一个新的对象,则使用 factory 来定义这个构造函数。
//工厂构造函数无法访问this。
class Singleton {
String name;
//工厂构造函数无法访问this,所以这里要用static
static Singleton _cache;
//工厂方法构造函数,关键字factory
factory Singleton([String name = 'singleton']) =>
Singleton._cache ??= Singleton._newObject(name);
//定义一个命名构造函数用来生产实例
Singleton._newObject(this.name);
}
//每个实例变量都隐含的具有一个 getter, 如果变量不是 final 的则还有一个 setter。
//可以通过实行 getter 和 setter 来创建新的属性, 使用 get 和 set 关键字定义 getter 和 setter。
//getter 和 setter 的好处是,你可以开始使用实例变量,后来 你可以把实例变量用函数包裹起来,而调用你代码的地方不需要修改。
class Rectangle {
num left;
num top;
num width;
num height;
Rectangle(this.left, this.top, this.width, this.height);
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
1.abstract关键字修饰class
2.继承的方式使用
3.接口的方式使用
不能被实例化,除非定义一个工厂构造函数。
抽象类通常用来定义接口, 以及部分实现。
抽象类通常具有抽象方法,抽象方法不需要关键字,以分号结束即可。
接口方式使用时,需要重写抽象类的成员变量和方法,包括私有的。
一个类可以implement一个普通类。Dart任何一个类都是接口。
一个类可以implement多个接口。
//实现call()方法可以让类像函数一样能够被调用
class ClassFunction {
call(String a, String b, String c) => '$a $b $c!';
}
main() {
var cf = new ClassFunction();
var out = cf("dongnao","flutter","damon");
print('$out');
print(cf.runtimeType);
print(out.runtimeType);
print(cf is Function);
}
main() {
K addCache(K key, V value) {
K temp = key;
print('${key}: ${value}');
return temp;
}
var key = addCache('dongnao', 'damon');
print(key);
}
函数的返回值类型
参数的类型
局部变量的类型
main() {
var p = Phone('123456');
print(p.mobileNumber);
}
class Phone {
final T mobileNumber;
Phone(this.mobileNumber);
}
要在使用构造函数时指定一个或多个类型,可将类型放在类名称后面的尖括号<…>中。
main() {
var footMassage = FootMassage();
var m = Massage(footMassage);
m.massage.doMassage();
}
class Massage {
final T massage;
Massage(this.massage);
}
class FootMassage {
void doMassage() {
print('脚底按摩');
}
}
实现泛型类型时,您可能希望限制其参数的类型,可以在<>里面使用extends。
Java中的泛型信息是编译时的,泛型信息在运行时是不存在的
Dart的泛型类型是固化的,在运行时也有可以判断的具体类型
var names = List();
print(names is List);//true
print(names.runtimeType); // List
使用import导入,内置库和其它库导入区别,怎么导入一个三方库
指定库前缀,选择性导入,延迟载入,自定义库
async和await
then,catchError,whenComplete
Event-Looper
Event Queue和Microtask Queue
任务调度
Future
scheduleMicrotask
dar基本学这些够用了,后面就可以进入Flutter学习了,只有dart学习之后,后面看flutter代码才会容易看懂,不然只会有种看天书的过程,当然大神除外。
Flutter中文网和提供的电子书可以反复学习,当文档查看
学习的几个方面
Flutter是谷歌开发的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作,并且Flutter是完全免费、开源的。
Flutter组件很多,不需要全部看,下面列举出自己学习过的组件
Text
Container
button
image
ListView
GridView
Sliver
route
Scaffold
bottomNavigationBar, Drawer
Navigator
Editor
Card
Progress
Dialog
WillPopScope
Wrap
Stack
GestureDetector
showBottomSheet
生命周期:掌握 Flutter 生命周期以及应用场景
1.【Flutter 实战】动画核心
需要的第三方库在这里找
http,dio网络请求库的使用
学完这几个,就可以开始写案例。
深入理解Flutter应用启动