《Flutter实战·第二版·1》Flutter环境搭建,Dart语言

167 阅读2分钟

 《Flutter实战·第二版》

1.Flutter环境搭建

1.1. 下载AndroidStudio,下载flutter对应的sdk,可以使用gitee clone.gitee.com/mirrors/Flu… 选中对应的版本sdk.flutter bin目录下双击dart 或者flutter下载到依赖文件到cache。

1.2. 设置环境变量 open  ~/.bash_profile

export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

export PUB_HOSTED_URL=https://pub.flutter-io.cn 
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

#添加flutter相关工具到path
export FLUTTER_ROOT=/Users/edy/Desktop/myuser/flutter
export PATH=${PATH}:$FLUTTER_ROOT/bin:$PATH

#添加dart相关工具到path
export DART_ROOT=/Users/edy/Desktop/myuser/flutter/bin/cache/dart-sdk
export PATH=${PATH}:$DART_ROOT/bin:$PATH


#Flutter镜像
#国内用户需要设置
export PUB_HOSTED_URL=https://pub.flutter-io.cn
#国内用户需要设置
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn


#Android环境变量
export ANDROID_HOME=/Users/edy/Library/Android/sdk
#Android平台工具路径
export PATH=${PATH}:/Users/edy/Library/Android/sdk/platform-tools
#Android-tools路径
export PATH=${PATH}:/Users/edy/Library/Android/sdk/tools
#Android-模拟器路径
export PATH=${PATH}:/Users/edy/Library/Android/sdk/emulator

1.3. 执行 flutter doctor

2.Dart语言

2.1. var关键字

1. var关键字 变量。
var t = "hi world";

2.2. dynamic关键字 和Object关键字

1.`dynamic`与`Object`声明的变量都可以赋值任意对象
    dynamic t;
    Object x;
    t = "hi world";
    x = 'Hello Object';
    //下面代码没有问题
    t = 1000;
    x = 1000;
2.`dynamic`与`Object`不同的是`dynamic`声明的对象编译器会提供所有可能的组合,而`Object`声明的对象只能使用 `Object` 的属性与方法, 否则编译器会报错  
    dynamic a;
    Object b = "";
    a = "";
    print(a.length);
    // print(b.length);//编译不通过。
    // print(a.len); //运行时报错。


2.3. final 和 const

一个 `final` 变量只能被设置一次,两者区别在于:`const` 变量是一个编译时常量(编译时直接替换为常量值),`final`变量在第一次使用时被初始化。
被`final`或者`const`修饰的变量,变量类型可以省略

final str = "hi world";
//final String str = "hi world"; 
const str1 = "hi world";

final a = DateTime.now();
//final 运行时定义常量。

2.4.空安全

int i;
print(i*8);//会报错,因为i没有初始化。

if(i != null) {
    print(i*8);//如果设置int? i;就不会走到这一步了。
}


Function? func;
func?.call();//fun不为空的时候则会调用。

2.5.函数

2.5.1.没有显式返回值,函数作为变量,函数作为参数。
如果没有显式声明返回值类型时,会默认当作dynamic处理。
isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

// 如果函数体只是一个表达式,可以使用=>来写。
bool isNoble (int atomicNumber)=> true ;   

//函数可以作为变量
var say = (str){
  print(str);
};
say("hi world");

//函数可以作为参数传递
//定义函数execute,它的参数类型为函数
void execute(var callback) {
    callback(); //执行传入的函数
}
//调用execute,将箭头函数作为参数传递
execute(() => print("xxx"))

2.5.2.函数参数分为位置参数,(位置参数可以有可选位置参数),可选命名参数。
print(say("zhangsna", "wnagwu","and"));
print(enableFlags(bold: true));

2.6.类 构造函数,命名构造函数

 Person.now() {
    print("命名构造函数");
  }
  //默认的构造函数的简写
  // Person(this.name, this.age);
  Person(String name,int age) {
    this._name = name;
    this.age = age;
    print("默认构造函数");
  }

  Person.setInfo(String name,int age) {
    this._name = name;
    this.age = age;
  }

2.7.mixin,抽象类,接口

2.7.1.mixin
mixin Eat {
  eat(){
    print("eat");
  }
}

mixin Walk {
  walk(){
    print("Walk");
  }
}

mixin Code {
  code(){
    print("Code");
  }
}

class Dog with Eat,Walk{
  show(){
    print('${this.eat()} ${this.walk()}');
  }
}

class Man extends Person with Eat,Walk,Code{
  show(){
    print('${this.eat()} ${this.walk()} ${this.code()}');
  }
}

2.7.2. 抽象类
class Person extends PersonAbstract {
  show(){
    this.eat();
    this.run();
    this.code();
    this.rrr();//"base ... rrr"
  }
}

abstract class PersonAbstract {
  //抽象类里面有非抽象方法。
  rrr(){
    print("base ... rrr");
  }
  void eat(){
   print("eat");
 }
 void run(){
   print("run");
 }
 void code(){
   print("code");
 }
}
2.7.3. 接口 可以实现多个接口,implement
class SqlDatabase implements Database,Database1 {
abstract class Database {
  String name;
  void insert();
  void delete();
  void update();
  void select();
}

//implements实现接口
class SqlDatabase implements Database {
  SqlDatabase(this.name);

  @override
  void delete() {
    // TODO: implement delete
  }

  @override
  void insert() {
    // TODO: implement insert
  }

  @override
  void select() {
    // TODO: implement select
  }

  @override
  void update() {
    // TODO: implement update
  }

  @override
  String name;

}

2.8 异步支持 Future

Dart类库有非常多的返回`Future`或者`Stream`对象的函数。 这些函数被称为**异步函数**,表示一个异步操作的最终完成(或失败)及其结果值的表示。
(2.8.1)Future.then 和 await 返回值实现是一样的。
Future.delayed(Duration(seconds: 2),(){
   return "hi world!";
}).then((data){
   print(data);
});
await Future.delayed(Duration(seconds: 2));
return "hello";
(2.8.2)Future.catchError,onError 失败的时候会走到这两个方法里面。
Future.delayed(Duration(seconds: 2),(){
   //return "hi world!";
   throw AssertionError("Error");  
}).then((data){
   //执行成功会走到这里  
   print("success");
}).catchError((e){
   //执行失败会走到这里  
   print(e);
});
(2.8.3)Future.whenComplete 不论是失败还是成功都会走到这里。
Future.delayed(Duration(seconds: 2),(){
   //return "hi world!";
   throw AssertionError("Error");
}).then((data){
   //执行成功会走到这里 
   print(data);
}).catchError((e){
   //执行失败会走到这里   
   print(e);
}).whenComplete((){
   //无论成功或失败都会走到这里
});

(2.8.4)Future.wait 等待其他Future执行完成,然后then再执行其他。
Future.wait([
  // 2秒后返回结果  
  Future.delayed(Duration(seconds: 2), () {
    return "hello";
  }),
  // 4秒后返回结果  
  Future.delayed(Duration(seconds: 4), () {
    return " world";
  })
]).then((results){
  print(results[0]+results[1]);
}).catchError((e){
  print(e);
});
2.8.5 async/await

为了避免下面的回调地狱

login("alice","******").then((id){
 //登录成功后通过,id获取用户信息    
 getUserInfo(id).then((userInfo){
    //获取用户信息后保存 
    saveUserInfo(userInfo).then((){
       //保存用户信息,接下来执行其他操作
        ...
    });
  });
})

2.8.5 消除1
ogin("alice","******").then((id){
  	return getUserInfo(id);
}).then((userInfo){
    return saveUserInfo(userInfo);
}).then((e){
   //执行接下来的操作 
}).catchError((e){
  //错误处理  
  print(e);
});
2.8.5 消除2
task() async {
   try{
    String id = await login("alice","******");
    String userInfo = await getUserInfo(id);
    await saveUserInfo(userInfo);
    //执行接下来的操作   
   } catch(e){
    //错误处理   
    print(e);   
   }  
}
2.8.6 Stream
Stream.fromFutures([
  // 1秒后返回结果
  Future.delayed(Duration(seconds: 1), () {
    return "hello 1";
  }),
  // 抛出一个异常
  Future.delayed(Duration(seconds: 2),(){
    throw AssertionError("Error");
  }),
  // 3秒后返回结果
  Future.delayed(Duration(seconds: 3), () {
    return "hello 3";
  })
]).listen((data){
   print(data);
}, onError: (e){
   print(e.message);
},onDone: (){
   print("onDone");
});

I/flutter (17666): hello 1
I/flutter (17666): Error
I/flutter (17666): hello 3
                   onDone