471Flutter学习笔记
2021-08-01 09:36:24 3 举报
AI智能生成
Flutter学习笔记
作者其他创作
大纲/内容
Dart语言
变量
在dart语言中:
变量是一个引用,未初始化的变量值是null;
变量是一个引用,未初始化的变量值是null;
Object、var与dynamic
Dart所有的变量皆对象
int是一个类
所有的基本类型都是一个class类,是与java中不同的;
所有的基本类型都是一个class类,是与java中不同的;
例如int:
abstract class int extends num
abstract class int extends num
var 在声明的变量赋值那一刻,就决定了它是什么类型
例如:
var j = "yulinmufeng";
j=100;(报错)
var l;
j = "yulinmufeng";
j=100;
var j = "yulinmufeng";
j=100;(报错)
var l;
j = "yulinmufeng";
j=100;
常量修饰符的区别:
dynamic与var的使用方法是相反的(动态的)。例如以下:
dynamic z = "yulinmufeng";
z= 100;
但在实际开发的情况下,动态的声明变量和静态的声明变量,dynamic和var变量定义的在执行效率上,不如var定义的变量;
dynamic一般在不确定是什么类型的时候,才会使用dynamic来声明变量;
dynamic一般使用频率不是很高;
var的缺点是,不能很好一眼就看出来是什么类型;
object与java中的表现是一样的;
dynamic与var的使用方法是相反的(动态的)。例如以下:
dynamic z = "yulinmufeng";
z= 100;
但在实际开发的情况下,动态的声明变量和静态的声明变量,dynamic和var变量定义的在执行效率上,不如var定义的变量;
dynamic一般在不确定是什么类型的时候,才会使用dynamic来声明变量;
dynamic一般使用频率不是很高;
var的缺点是,不能很好一眼就看出来是什么类型;
object与java中的表现是一样的;
final与const的区别
final
final:
用法与java中是一样的;
用法与java中是一样的;
const
const:
在赋值之后,是不能再次进行赋值的,与final是一样的;
final是运行期常量;
const是编译期常量;
const比final的运行效率要高;
在赋值之后,是不能再次进行赋值的,与final是一样的;
final是运行期常量;
const是编译期常量;
const比final的运行效率要高;
特性:
final i = 1;
const j = 1;
//因为i是运行时确定,所以不能给编译时候就要确定的变量赋值
//const z= i;(不可以)
//可以使用另一个编译时确定的变量给它赋值
const z=j+1;(这样是可以的)
final i = 1;
const j = 1;
//因为i是运行时确定,所以不能给编译时候就要确定的变量赋值
//const z= i;(不可以)
//可以使用另一个编译时确定的变量给它赋值
const z=j+1;(这样是可以的)
使用场景:
均可以声明一个不可变量的声明
均可以声明一个不可变量的声明
内置类型
数据类型:num
int
说明:
1、通过源码中的注释,可以看出int类型,占用的字节,要看编译运行的平台,
分为4字节或者8字节,但可以认为和java一样,为4个字节;
2、dart当中的int,在编码的时候,可以将int当成java的int long来使用,如果我们写的
dart代码超过了4个字节,那么dart会将其编译成类似的java当中的long否则编译成java当中的
short或者int;
3、i.bitlength=占用的字节;
4、在使用上和java的方式是一样的;
备注:原则上java和Dart语言中的int不能拿到一块进行对比,因为Dart中为class类,而java是基本
数据类型;
1、通过源码中的注释,可以看出int类型,占用的字节,要看编译运行的平台,
分为4字节或者8字节,但可以认为和java一样,为4个字节;
2、dart当中的int,在编码的时候,可以将int当成java的int long来使用,如果我们写的
dart代码超过了4个字节,那么dart会将其编译成类似的java当中的long否则编译成java当中的
short或者int;
3、i.bitlength=占用的字节;
4、在使用上和java的方式是一样的;
备注:原则上java和Dart语言中的int不能拿到一块进行对比,因为Dart中为class类,而java是基本
数据类型;
double
说明:
1、如果要表示float类型时,只能使用double来表示;
2、Dart中的double和在java中的double在使用方式上市一样的;
1、如果要表示float类型时,只能使用double来表示;
2、Dart中的double和在java中的double在使用方式上市一样的;
说明:
1、num内置数据类型只有两个int和double;
1、num内置数据类型只有两个int和double;
字符串类型:String
说明:
1、在声明上与java一样;
String str = "走,一起去搓澡!";(dart)
2、方法String.format("&s%d",str,i);java中格式化一个字符串;
3、在Dart中更方便来格式化字符串,
String txt = "$str$num";(Dart语言字符串拼接)
String txt = "${str}s去搓澡$num";
4、在Dart中可以使用单引号和双引号两种声明方式,所以可以混合使用;
String s1 = "'test'";
String s2 = '"test"';
5、r前缀,就不进行换行------s3 = r"\n"
6、三引号使用"""sss"""
三引号在使用的时候,是可以进行内容换行的;
1、在声明上与java一样;
String str = "走,一起去搓澡!";(dart)
2、方法String.format("&s%d",str,i);java中格式化一个字符串;
3、在Dart中更方便来格式化字符串,
String txt = "$str$num";(Dart语言字符串拼接)
String txt = "${str}s去搓澡$num";
4、在Dart中可以使用单引号和双引号两种声明方式,所以可以混合使用;
String s1 = "'test'";
String s2 = '"test"';
5、r前缀,就不进行换行------s3 = r"\n"
6、三引号使用"""sss"""
三引号在使用的时候,是可以进行内容换行的;
布尔类型:bool
说明:
1、bool来定义布尔类型;
2、定义方式:
bool b= false;
1、bool来定义布尔类型;
2、定义方式:
bool b= false;
数据类型:List
说明:
1、List数组
2、Dart语言泛型
List<String> list = new List();
3、直接在声明的时候赋值
List<int> list = [1,2,3,4,5];
4、Dart语言取数据(像java数组一样通过下标取元素)
int item0 = list[0];
5、遍历数组(与java中相似)
for(var o in list){
}
for(var j= 0; j < list.length; ++j){
}
6、List对象不可变(const [1,2,3,4,5] = 意思就是可以再进行添加任何的元素)
List<int> list = const [1,2,3,4,5];
list.add(1);报错了
7、const修饰的是变量,也就是引用,那么变量就不能够在重新引用其他的对象了
const List<int> list = [1,2,3,4,5];
list = [3,4];报错了
list.add(1);报错了
1、List数组
2、Dart语言泛型
List<String> list = new List();
3、直接在声明的时候赋值
List<int> list = [1,2,3,4,5];
4、Dart语言取数据(像java数组一样通过下标取元素)
int item0 = list[0];
5、遍历数组(与java中相似)
for(var o in list){
}
for(var j= 0; j < list.length; ++j){
}
6、List对象不可变(const [1,2,3,4,5] = 意思就是可以再进行添加任何的元素)
List<int> list = const [1,2,3,4,5];
list.add(1);报错了
7、const修饰的是变量,也就是引用,那么变量就不能够在重新引用其他的对象了
const List<int> list = [1,2,3,4,5];
list = [3,4];报错了
list.add(1);报错了
映射集合:Map
说明:
1、声明一个映射集合如下:
Map<int,int> map = {1:1,2:2,3:3};
map[1]输出值=1,通过key来获取value;
2、修改一个元素的话,也是可以用个key来修改value的值
map[1] = 100;
3、用const声明map和list是一样的;
var map1 = const{1:1,2:2};
const var map1 = {1:1,2:2};
如果取一个不存在的数据会返回null;
4、迭代器遍历与java是一样的
1、声明一个映射集合如下:
Map<int,int> map = {1:1,2:2,3:3};
map[1]输出值=1,通过key来获取value;
2、修改一个元素的话,也是可以用个key来修改value的值
map[1] = 100;
3、用const声明map和list是一样的;
var map1 = const{1:1,2:2};
const var map1 = {1:1,2:2};
如果取一个不存在的数据会返回null;
4、迭代器遍历与java是一样的
Unicode:Runes
说明:
1、Runes:特殊字符表示类,其实真正表示的是,Unicode32=字符编码标准,这个标准可以表示任何
字符,就是所有的字符;
2、var clapping = '\u{1f44f}';//5个16进制需要使用{},用字符串数据一个拍手的图标
3、代码点与代码单元(可以自己去搜索一下,这两个的区别)
1、Runes:特殊字符表示类,其实真正表示的是,Unicode32=字符编码标准,这个标准可以表示任何
字符,就是所有的字符;
2、var clapping = '\u{1f44f}';//5个16进制需要使用{},用字符串数据一个拍手的图标
3、代码点与代码单元(可以自己去搜索一下,这两个的区别)
标识符:Symbols
说明:
1、(很少用到,作为了解)Symbols标识符,类似C、C++中的宏(但不完全相似)
2、定义一个symbols
var a = #asdfg;
a输出的时候就是为:symbols
使用点一般在switch中使用,其他的使用点就不多;
switch(a){
case #A:
break;
case #sadsad:
break;
}
1、(很少用到,作为了解)Symbols标识符,类似C、C++中的宏(但不完全相似)
2、定义一个symbols
var a = #asdfg;
a输出的时候就是为:symbols
使用点一般在switch中使用,其他的使用点就不多;
switch(a){
case #A:
break;
case #sadsad:
break;
}
说明:
java中有8大基本数据类型;
Dart中有7大内置类型;
java中有8大基本数据类型;
Dart中有7大内置类型;
操作符
类型判定操作符
类型转换:as
说明:
1、Dart语言中不支持java中强制类型转换的方法
2、Dart例如:
num j = 1;
//类型转换,不支持java的转化:(int)强转写法
int i = j as int;
1、Dart语言中不支持java中强制类型转换的方法
2、Dart例如:
num j = 1;
//类型转换,不支持java的转化:(int)强转写法
int i = j as int;
类型判断:is、!is
说明:
1、dart语言中没有java中的instantof,而是需要is来实现;
if(index is int){
}
2、不属于int类型则命中if
if(index is! int){
}
1、dart语言中没有java中的instantof,而是需要is来实现;
if(index is int){
}
2、不属于int类型则命中if
if(index is! int){
}
赋值操作符:??=
说明:
1、java保证k后续使用时一定不为null
String k;
if(null == k){
k = "123";
}
2、dart语言中,??= 安全赋值,如果k有值,这句话就当它不存在,如果k没有值就赋值456
k ??= "456";
1、java保证k后续使用时一定不为null
String k;
if(null == k){
k = "123";
}
2、dart语言中,??= 安全赋值,如果k有值,这句话就当它不存在,如果k没有值就赋值456
k ??= "456";
条件表达式
三目表达式:condition?expr1:expr2
说明:
1、跟java中的三目运算符是一样的
1、跟java中的三目运算符是一样的
expr1 ?? expr2
说明:
1、如果expr1不为null,那么就返回expr1,否则就返回expr2
例如:
String k = "123";
var v = k ?? "789";
那么v= 123;
如果:
k = null;
var v = k ?? "789";
那么v = 789;
1、如果expr1不为null,那么就返回expr1,否则就返回expr2
例如:
String k = "123";
var v = k ?? "789";
那么v= 123;
如果:
k = null;
var v = k ?? "789";
那么v = 789;
级联操作符:..
说明:
1、java中的话,就像是建造者是一样的,在每次返回的时候,都是他本身,这样的话就可以一直链式调用;
2、dart中级联操作符
new Builder()..a()..b();
class Builder {
void a(){
}
void b(){
}
}
1、java中的话,就像是建造者是一样的,在每次返回的时候,都是他本身,这样的话就可以一直链式调用;
2、dart中级联操作符
new Builder()..a()..b();
class Builder {
void a(){
}
void b(){
}
}
安全操作符:?.
说明:
1、在正常开发的时候,经常遇到的异常就是空指针异常;
但是在dart语言中,可以使用?.来解决这个功能。
2、grovy和kotlin语言中都有这个?.此功能。
1、在正常开发的时候,经常遇到的异常就是空指针异常;
但是在dart语言中,可以使用?.来解决这个功能。
2、grovy和kotlin语言中都有这个?.此功能。
方法
可选命题参数
说明:
1、可选命题参数又名可选命名参数,并且在使用的时候,跟可选位置参数,有点相似;如下:
void fun({int i,int j}){}
在上面方法调用的时候,传递的参数,要以键值对的形式进行传递;如下:
fun(j:10,i:11);//这样调用
2、也可以设置默认参数值的;如下:
void fun({int i = 2,int j}){}
3、应用场景,不需要再像java一样,写一大堆的重载函数,并且能够提供参数默认值;
1、可选命题参数又名可选命名参数,并且在使用的时候,跟可选位置参数,有点相似;如下:
void fun({int i,int j}){}
在上面方法调用的时候,传递的参数,要以键值对的形式进行传递;如下:
fun(j:10,i:11);//这样调用
2、也可以设置默认参数值的;如下:
void fun({int i = 2,int j}){}
3、应用场景,不需要再像java一样,写一大堆的重载函数,并且能够提供参数默认值;
可选位置参数
说明:
1、java中没有;
2、dart语言中
void fun([int i, int j]){}
可选参数位置,只要是用[]括起来的参数,这个方法在被调用的时候,就可以传递想要传递的参数,
但是在参数传递的时候,也可以在参数中,直接给参数进行辅助,就是固定的参数,就设置为默认值;
如:void fun([int i, int j = 2]){}
如上如果要给j就行传值的话,就必须保证要给i传值,因为有位置要求;
3、应用场景,不需要再像java一样,写一大堆的重载函数,并且能够提供参数默认值;
1、java中没有;
2、dart语言中
void fun([int i, int j]){}
可选参数位置,只要是用[]括起来的参数,这个方法在被调用的时候,就可以传递想要传递的参数,
但是在参数传递的时候,也可以在参数中,直接给参数进行辅助,就是固定的参数,就设置为默认值;
如:void fun([int i, int j = 2]){}
如上如果要给j就行传值的话,就必须保证要给i传值,因为有位置要求;
3、应用场景,不需要再像java一样,写一大堆的重载函数,并且能够提供参数默认值;
默认参数值
一等方法对象
说明:
1、
void fun(Function f){
}
void main(){
//方法都是对象,可以赋值给Function变量
Function f = fun;
f((int i,int j,String str){
return "1";
});
}
以上代码运行报错,原因是参数对象不匹配,传的是Function,但是参数值确实多个;
//定义一个类型:F类型,这个F类型其实就是一个方法,接受两个int 参数,返回void
typedef void F(int i,int j);
void fun2(F f){
f(1);报错,此时会检测传递了几个参数;
}
2、在java中接口调用的方法,在dart中也是不同的;
java如下:
class OnClickListener{
void onClick(){}
}
class Button{
void setOnClickListener(OnClickListener listener){
}
}
dart如下:
typedef void onClick();
class Button{
void setOnClickListener(onClick listener){
listener();
}
}
1、
void fun(Function f){
}
void main(){
//方法都是对象,可以赋值给Function变量
Function f = fun;
f((int i,int j,String str){
return "1";
});
}
以上代码运行报错,原因是参数对象不匹配,传的是Function,但是参数值确实多个;
//定义一个类型:F类型,这个F类型其实就是一个方法,接受两个int 参数,返回void
typedef void F(int i,int j);
void fun2(F f){
f(1);报错,此时会检测传递了几个参数;
}
2、在java中接口调用的方法,在dart中也是不同的;
java如下:
class OnClickListener{
void onClick(){}
}
class Button{
void setOnClickListener(OnClickListener listener){
}
}
dart如下:
typedef void onClick();
class Button{
void setOnClickListener(onClick listener){
listener();
}
}
匿名方法
说明:
1、匿名方法,lambda表达式
1、匿名方法,lambda表达式
异常
说明:
(1)介绍catch的参数;
1、dart中和java中的异常抛出不一样;如下:
void test(){
throw new Exception("你好");
}
void main(){
try{
test();
}catch(e){}
}
dart中虽然不强制你去捕获异常,但是类似java中try..catch异常也是可以的;如上面的代码;
2、java中针对不用的异常,就捕获不同的异常;但是在dart中是不可以的;
3、catch(e)中不仅可以接受一个参数e,其实可以同时接受好两个参数(最多两个参数),catch(e,s)这样;
e:就是抛出的异常对象;
s:就是调用栈信息,StackTrace
(2)根据不同的异常类型,进行不同的处理;
语法on TYPE catch....
try{
test();
}on Exception catch(e,s){
}on intcatch(e){
}on Stringcatch(e){
}
(1)介绍catch的参数;
1、dart中和java中的异常抛出不一样;如下:
void test(){
throw new Exception("你好");
}
void main(){
try{
test();
}catch(e){}
}
dart中虽然不强制你去捕获异常,但是类似java中try..catch异常也是可以的;如上面的代码;
2、java中针对不用的异常,就捕获不同的异常;但是在dart中是不可以的;
3、catch(e)中不仅可以接受一个参数e,其实可以同时接受好两个参数(最多两个参数),catch(e,s)这样;
e:就是抛出的异常对象;
s:就是调用栈信息,StackTrace
(2)根据不同的异常类型,进行不同的处理;
语法on TYPE catch....
try{
test();
}on Exception catch(e,s){
}on intcatch(e){
}on Stringcatch(e){
}
类
类说明:
1、私有的类和属性,在dart语言中,表示方式;
//包括类的定义 如果使用 _ 开头,意味着这个类就是private
class Point{
int _x;//使用_开始命名的变量,就是java的private,在外面不可以调用
int y;
}
1、私有的类和属性,在dart语言中,表示方式;
//包括类的定义 如果使用 _ 开头,意味着这个类就是private
class Point{
int _x;//使用_开始命名的变量,就是java的private,在外面不可以调用
int y;
}
构造函数
构造函数语法糖Point(this._x,this.y)
说明:
class Point{
int _x;
int y;
Point(this._x,this.y);//构造函数
}
Point(this._x,this.y);
此构造方法相对于java中来说,比之前要简单的多;
dart语言中是不能进行方法重载的,但是我们是有定义多个方法的需求;
class Point{
int _x;
int y;
Point(this._x,this.y);//构造函数
}
Point(this._x,this.y);
此构造方法相对于java中来说,比之前要简单的多;
dart语言中是不能进行方法重载的,但是我们是有定义多个方法的需求;
命名构造函数
说明:
1、dart语言中是不能进行方法重载的,但是我们是有定义多个方法的需求;
命名构造方法(可以根据名字就可以直接看出来这个构造方法是干嘛用的,这也是为什么有了命名构造方法,
还可以有可选参数构造方法的原因):
Point.Y(this.y);
Point._X(this._X);
调用方式:var point = new Ponit.X(1);
2、构造方法的可选参数
Point(int x,int y){}//不用加this了
1、dart语言中是不能进行方法重载的,但是我们是有定义多个方法的需求;
命名构造方法(可以根据名字就可以直接看出来这个构造方法是干嘛用的,这也是为什么有了命名构造方法,
还可以有可选参数构造方法的原因):
Point.Y(this.y);
Point._X(this._X);
调用方式:var point = new Ponit.X(1);
2、构造方法的可选参数
Point(int x,int y){}//不用加this了
参数初始化列表
说明:
参数初始化列表(初始化类中的属性,可以不写方法体):
Point.XY():_x=1,y=2;
Point.fromMap(Map map):_x = map['x'],y=map['y'];
参数初始化列表(初始化类中的属性,可以不写方法体):
Point.XY():_x=1,y=2;
Point.fromMap(Map map):_x = map['x'],y=map['y'];
重定向构造函数
说明:
重定向构造函数
class View{
View(int content,int attr);
//重定向构造函数
View.a(int context):this(context,0);
}
重定向构造函数
class View{
View(int content,int attr);
//重定向构造函数
View.a(int context):this(context,0);
}
常量构造函数
说明:
class ImmutabelPoint{
final int x;
final int y;
//常量构造方法
const ImmutabelPoint(this.x,this.y);
}
使用new来创建常量构造方法的对象,就和普通的对象没有区别;
但是使用const来创建多个对象,传递的参数一样,表示这几个对象是同一个编译器常量对象(必须定义常量构造函数)
void main(){
var p1 = const ImmutabelPoint(1,1);
var p1 = const ImmutabelPoint(1,1);
print(p1.hashCode == p2.hashCode);//true
print(p1 == p2);//true
}
class ImmutabelPoint{
final int x;
final int y;
//常量构造方法
const ImmutabelPoint(this.x,this.y);
}
使用new来创建常量构造方法的对象,就和普通的对象没有区别;
但是使用const来创建多个对象,传递的参数一样,表示这几个对象是同一个编译器常量对象(必须定义常量构造函数)
void main(){
var p1 = const ImmutabelPoint(1,1);
var p1 = const ImmutabelPoint(1,1);
print(p1.hashCode == p2.hashCode);//true
print(p1 == p2);//true
}
工厂构造函数
说明:
在命名构造函数前面其实加一个factory就是工厂构造函数;
在工厂的构造方法中,不可以使用this
在命名构造函数前面其实加一个factory就是工厂构造函数;
在工厂的构造方法中,不可以使用this
Getter与Setter
说明:
每一个实例属性,变量都会有一个隐式的get,非final 还有set方法;
每一个实例属性,变量都会有一个隐式的get,非final 还有set方法;
操作符重载
说明:
操作符重载:把已经定义的、有一定功能的操作符进行重新定义;
例如:
<、+、|、[]、>、/、^、[]=、<=、~/、&、~、>=、*、<<、==、-、%、>>
操作符重载:把已经定义的、有一定功能的操作符进行重新定义;
例如:
<、+、|、[]、>、/、^、[]=、<=、~/、&、~、>=、*、<<、==、-、%、>>
抽象类与接口
说明:
1、abstract
使用abstract修饰符定义一个抽象类,抽象类中允许出现无方法的方法与java没有什么区别,不可以多继承;
abstract class Parent{
String name;
void printName();//抽象方法,不需要在方法前声明abstract
}
2、接口
与java不同,Dart中没有interface关键字,Dart中每个类都隐式的定义了一个包含所有势力成员的接口,
并且这个类实现了这个接口。如果你想创建类M来支持类N的方法,而不想继承N的实现,则类M应该实现N的接口;
每一类都可以看作为一个接口,Dart语言中没有分的太清楚。
1、abstract
使用abstract修饰符定义一个抽象类,抽象类中允许出现无方法的方法与java没有什么区别,不可以多继承;
abstract class Parent{
String name;
void printName();//抽象方法,不需要在方法前声明abstract
}
2、接口
与java不同,Dart中没有interface关键字,Dart中每个类都隐式的定义了一个包含所有势力成员的接口,
并且这个类实现了这个接口。如果你想创建类M来支持类N的方法,而不想继承N的实现,则类M应该实现N的接口;
每一类都可以看作为一个接口,Dart语言中没有分的太清楚。
混合mixins
说明:
Mixins是一种在多类继承中重用一个类代码的方法;而且被Mixins侵入的类
不能有构造函数。
此功能就是相对于弥补java不能多继承的问题;
class A{
void a(){}
}
class B{
void b(){}
}
class C with A,B{
void c(){}
}
还有一种写法:
class C = Object with A,B;//C类就是AB的混合类;
可以在C类中调用AB类中的方法,满足了我们的多继承的需求,但是不能重写;
使用混入的话可以弥补我们没有多线程的缺陷;
Mixins是一种在多类继承中重用一个类代码的方法;而且被Mixins侵入的类
不能有构造函数。
此功能就是相对于弥补java不能多继承的问题;
class A{
void a(){}
}
class B{
void b(){}
}
class C with A,B{
void c(){}
}
还有一种写法:
class C = Object with A,B;//C类就是AB的混合类;
可以在C类中调用AB类中的方法,满足了我们的多继承的需求,但是不能重写;
使用混入的话可以弥补我们没有多线程的缺陷;
可调用的类
说明:
class Test{
void call()}{}
}
调用(只有call方法的时候才能这样调用)
test();就相当于调用了call()方法;
也可以直接调用
test.call();
class Test{
void call()}{}
}
调用(只有call方法的时候才能这样调用)
test();就相当于调用了call()方法;
也可以直接调用
test.call();
环境搭建
Flutter配置开发环境
(0)网址:https://flutterchina.club/setup-windows/
(1)使用镜像配置环境变量
同时可以在用户中心和系统中心进行配置环境变量
mac
说明:以下是mac本配置的方式:(与window方式不一样,但是Flutter中文网上给的镜像的方式是错误的,给的mac上配置的方式,特此说明)
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
window
说明:window配置镜像的方式如下。
PUB_HOSTED_URL=https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
PUB_HOSTED_URL=https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
(2)下载Flutter的SDK
网址:https://flutter.dev/docs/development/tools/sdk/releases#windows
下载完成之后,进行解压,然后在进行环境变量的配置
配置到path路径下。
配置到path路径下。
环境变量配置:
D:\install_files\flutter\flutter_sdk\flutter\bin
配置完成之后,
现在就可以使用flutter命令了
D:\install_files\flutter\flutter_sdk\flutter\bin
配置完成之后,
现在就可以使用flutter命令了
命令测试
打开cmd命令,执行以下命令:
flutter doctor
执行结果可以查看,flutter需要的条件有哪些,哪些还没有安装,都会给你列出来。
(如上图)
flutter doctor
执行结果可以查看,flutter需要的条件有哪些,哪些还没有安装,都会给你列出来。
(如上图)
(3)安装插件
以上所有工作已经完成后
打开android studio进行安装Flutter插件,安装成功后,对android studio进行重启
然后在创建新项目的时候,就可以创建flutter项目了
打开android studio进行安装Flutter插件,安装成功后,对android studio进行重启
然后在创建新项目的时候,就可以创建flutter项目了
(4)所有的准备工作已经完成
(5)遇到的第一个问题
错误日志如下:
Could not determine the dependencies of task ‘:app:compileDebugJavaWithJavac‘.
Could not determine the dependencies of task ‘:app:compileDebugJavaWithJavac‘.
解决方法:
1、修改android目录下的build.gradle文件中的所有的google()和jcenter()换成阿里云的镜像
1、修改android目录下的build.gradle文件中的所有的google()和jcenter()换成阿里云的镜像
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'http://download.flutter.io'}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'http://download.flutter.io'}
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext.kotlin_version = '1.3.50'
repositories {
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'http://download.flutter.io'}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
// google()
// jcenter()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
maven { url 'http://download.flutter.io'}
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
解决方法:
2、修改flutter sdk下的flutter.gradle文件,具体目录是flutter\packages\flutter_tools\gradle
2、修改flutter sdk下的flutter.gradle文件,具体目录是flutter\packages\flutter_tools\gradle
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
异步编程
isolate(Dart中的异步机制)
像进程一样的线程
事件驱动
事件队列与微任务队列
微任务队列的优先级是最高的
跟普通的任务并列好几个的时候,就算是微任务后提交,也会先把微任务执行完,之后再执行普通的任务!
跟普通的任务并列好几个的时候,就算是微任务后提交,也会先把微任务执行完,之后再执行普通的任务!
微任务队列
会不会插队执行呢?
Futura
在异步编程中随处可见,代表了事件结果
对异步编程的异常捕获
等待多个异步结果进行后续操作:wait方法
Stream
异步事件流
Stream(流) 在 Dart API 中也经常出现,表示发出的一系列的异步数据。 Stream 是一个异步数据源,它是 Dart 中处理异步事件流的统一 API。
操作订阅者:取消、异常、暂停继续
广播模式:允许多个订阅者
Stream有两种订阅模式:单订阅和多订阅。单订阅就是只能有一个订阅者,上面的使用我们都是单订阅模式,而广播是可以有多个订阅者。通过 Stream.asBroadcastStream() 可以将一个单订阅模式的 Stream 转换成一个多订阅模式的 Stream,isBroadcast 属性可以判断当前 Stream 所处的模式。
Stream有两种订阅模式:单订阅和多订阅。单订阅就是只能有一个订阅者,上面的使用我们都是单订阅模式,而广播是可以有多个订阅者。通过 Stream.asBroadcastStream() 可以将一个单订阅模式的 Stream 转换成一个多订阅模式的 Stream,isBroadcast 属性可以判断当前 Stream 所处的模式。
async/await
async声明为异步方法,返回Future
await等待执行结果,异步变同步(多个异步串行执行)
使用`async`和`await`的代码是异步的,但是看起来很像同步代码。当我们需要获得A的结果,再执行B,时,你需要`then()->then()`,但是利用`async`与`await`能够非常好的解决回调地狱的问题
示例
//async 表示这是一个异步方法,await必须再async方法中使用
//异步方法只能返回 void和Future
Future<String> readFile() async {
//await 等待future执行完成再执行后续代码
String content = await new File("/Users/xiang/enjoy/a.txt").readAsString();
String content2 = await new File("/Users/xiang/enjoy/a.txt").readAsString();
//自动转换为 future
return content;
}
//异步方法只能返回 void和Future
Future<String> readFile() async {
//await 等待future执行完成再执行后续代码
String content = await new File("/Users/xiang/enjoy/a.txt").readAsString();
String content2 = await new File("/Users/xiang/enjoy/a.txt").readAsString();
//自动转换为 future
return content;
}
0 条评论
下一页