第一章 Flutter 入门
第1节 Flutter 命令详解
-h, --help Print this usage information.
-v, --verbose Noisy logging, including all shell commands
executed.
If used with --help, shows hidden options.
-d, --device-id Target device id or name (prefixes allowed).
--version Reports the version of this tool.
--suppress-analytics Suppress analytics reporting when this command runs.
--bug-report Captures a bug report file to submit to the Flutter
team.
Contains local paths, device identifiers, and log
snippets.
--packages Path to your ".packages" file.
(required, since the current directory does not
contain a ".packages" file)
Available commands:
analyze Analyze the project's Dart code.
assemble Assemble and build flutter resources.
attach Attach to a running application.
bash-completion Output command line shell completion setup scripts.
build Flutter build commands.
channel List or switch flutter channels.
clean Delete the build/ and .dart_tool/ directories.
config Configure Flutter settings.
create Create a new Flutter project.
devices List all connected devices.
doctor Show information about the installed tooling.
drive Runs Flutter Driver tests for the current project.
emulators List, launch and create emulators.
format Format one or more dart files.
help Display help information for flutter.
install Install a Flutter app on an attached device.
logs Show log output for running Flutter apps.
make-host-app-editable Moves host apps from generated directories to
non-generated directories so that they can be edited
by developers.
precache Populates the Flutter tool's cache of binary
artifacts.
pub Commands for managing Flutter packages.
run Run your Flutter app on an attached device.
screenshot Take a screenshot from a connected device.
test Run Flutter unit tests for the current project.
upgrade Upgrade your copy of Flutter.
version List or switch flutter versions.
Run "flutter help " for more information about a command.
Run "flutter help -v" for verbose help output, including less commonly used
options.
1.1 build
flutter build apk —help
输出: ${flutter_project}/build/app/outputs
flutter build ios
输出目录:${flutter_project}/build/ios/iphoneos/Runner.app
错误1: com.example.flutterApp App Id 错误
Xcode's output:
↳
note: Using new build systemnote: Planning buildnote: Constructing build descriptionerror: Failed to register bundle identifier. The app identifier "com.example.flutterApp" cannot be registered
to your development team. Change your bundle identifier to a unique string to try again. (in target 'Runner' from project 'Runner')error: No profiles for 'com.example.flutterApp' were found:
Xcode couldn't find any iOS App Development provisioning profiles matching 'com.example.flutterApp'. (in target 'Runner' from project 'Runner')
分析: 苹果IOS每个新建的APP Id都需要通过云端验证其唯一性,不唯一无法编译成功
解决:Xcode -> Runner(点击)-> signing & Capabilities -> Bundle Identifier(修改)
1.2 dependence
flutter upgrade | 升级 Flutter SDK(此命令会同时更新 Flutter SDK 和你的 Flutter 项目依赖包) |
---|---|
flutter packages get | 获取项目所有的依赖包(只更新项目依赖包,不包括 Flutter SDK) |
flutter packages upgrade | 获取项目所有依赖包的最新版本(只更新项目依赖包,不包括 Flutter SDK) |
1.3 Config
flutter devices找不到Android 设备
$ flutter config --android-sdk /path/to/android/sdk
$ flutter config --android-studio-dir /path/to/android/studio
flutter config --gradle-dir /path/to/gradle
第2节 Dart基本语法入门
2.1 Dart 语言特点
Dart中,一切(数字类型、方法、null等)都是对象
Dart支持范型,List表示一个整型的数据列表,List则是一个对象的列表,其中可以装任意对象
Dart支持顶层方法(如main方法),也支持类方法或对象方法,同时你也可以在方法内部创建方法
Dart支持顶层变量,也支持类变量或对象变量
Dart没有public protected private等关键字,
Dart中若某个变量以下划线_ 开头,代表这个变量在库中是私有的
2.2 变量与常量
var a = 1; //变量,自动推断其数据类型
dynamic c = 0.5; //对象,自动推断其数据类型
const Num1 = 10; // const赋值必须是编译时常量,编译时就确定值了
2.3 数组
var arr = [1, 2, 3, 4, 5]; //自动推断为 数字数组
List arr2 = ['hello', 'world', "123", "456"]; //字符串数组
List arr3 = [1, true, 'haha', 1.0];//对象数组
2.4 函数
- 函数的返回值
//声明函数返回值类型
int add(int a, int b){
return a + b;
}
//不声明函数返回值类型
add2(int a, int b){
return a + b;
}
// return 返回语句的简写: =>
add3(a,b) => a + b;
-
参数
sayHello1({String name}) { print("这是一个有 命名参数的函数: $name"); } sayHello2({name: String}) { print("带 命名参数 的函数的第二种写法:$name"); } sayHello3({@required String name}) { print("必须穿参数,否则报错:$name"); } //位置参数用[] 包裹,可传可不传,放在参数列表的最后,可以是多个 sayHello(String name, int age, [String a, int b]){ if(a != null){ sb.write("这是a: $a"); } }
-
函数的一些特殊用法
-
函数作为参数传入
void main(){ var arr = [1,2,3]; arr.forEach(printNum); } printNum(int param){ print('$param'); } // f 是一个函数 void forEach(void f(E element)) { for (E element in this) f(element); }
-
函数变量写法
void main(){ var f1 = printNum; Function f2 = printNum; var f3 = (int a) => print("a = $a"); f1(1); // 1 f2(2); // 2 f3(6); // a = 6 } printNum(int param){ print('$param'); }
-
匿名函数
void main(){ myTest((params){ print(params); }); var callback = (params){ print(params); }; myTest(callback); myTest(print); } myTest(Function callback){ callback("you are wonderful"); //callback 匿名函数 }
-
2.5 运算符
-
is and is!
var s = "hello"; var num = 6; print(s is String); // true is运算符用于判断变量是某个类型的数据 print(num is! String); // true is!运算符用于判断变量不是某个类型的数据
-
取整
int k = 1; int j = 2; print(k ~/ j); // 0 '~/'运算符 取整
-
强转
//as 运算符 将对象转换为特定类型 if(emp is Person){ //如果 emp 是 Person 类型 赋值 emp.firstName = "ABC"; } //如果 emp 不是 person类型 或为 空,上面什么都不做 //下方代码:如果emp为空 或不是Person类型,将抛出异常;如果emp是Person类型,给其赋值; (emp as Person).firstName = "ABC";
-
??
var str1 = "hello", str2 = null; print(str1?.length); // 5 若 str1 有length 属性 则忽略'?'的作用 print(str2?.length); // null 若 str2 没有length的属性 则返回null
-
..
级联使用'..'运算符调用对象的方法或成员变量,可以连续使用'..'运算符;但不能再返回 void 上构造级联 示例: var button = queaySelector('#confirm'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!')); 等价于: querySelector('#confirm') ..text = 'Confirm' ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!')); 也可以嵌套级联: final addressBook = (AddressBookBuilder() ..name = 'jenny' ..email = '[email protected]' ..phone = (PhoneNumberBuilder() ..number = '415-555-0100' ..label = 'home') .build()) .build(); 注意:在返回实际对象的函数上构造级联要小心返回的是否是void,在void上构造级联会报错 var sb = StringBuffer(); sb.write('foot') // 此时返回void ..write('bar'); //在void上构造级联会报错
2.6 流程控制
for (var i in List){
print (i);
}
try{
1 ~/ 0;
} on IntegerDivisionByZeroException { // 铺货指定类型的异常
print("error");
} finally{
print("over");
}
2.7 类
2.7.1 构造方法
class Point{
num x,y;
Point(this.x,this.y);
//类的命名构造方法
Point.origin(){
x=0;
y=0;
}
}
// var p1 = new Point.origin();
2.7.2 继承
class Father {
String name;
Father.fromJson(Map data){ //父类中没有默认构造方法,只有这一个命名构造方法
print("这是父类的fromJson方法");
}
}
class Child extends Father{
Child.fromJson(Map data) : super.fromJson(data){
print("这是子类的fromJson方法");
}
}
void main(){
Map map = new Map();
Child child = new Child.fromJson(map); // 只能用fromJson进行初始化
}
//out
I/flutter (22196): 这是父类的fromJson方法
I/flutter (22196): 这是子类的fromJson方法
2.7.3 set get
class Rectangle {
num left, top, width, height;
//构造方法
Rectangle(this.left, this.top, this.width, this.height);
//为 right 和 bottom两个成员变量提供 getter 和 setter 方法
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
//设置
void main(){
Rectangle rect = new Rectangle(10, 10, 10, 10);
rect.right = 10; // 调用 set
var rect.right; // 调动 get
}
2.7.4 抽象类
abstract class Doer { //使用 abstract 修饰的类,就是抽象类
void doSomething(); //没有方法体的方法 就是抽象方法,抽象方法需要子类去实现
void greet(){ // 有方法体的方法,是普通的 非抽象方法
print("hello world!");
}
}
2.7.5 枚举
enum Color { red, green, blue}
2.7.6 合并两个类(mixins)
class A{
a(){
print(" 这是 A 的 a 方法");
}
}
class B{
b(){
print(" 这是 B 的 b 方法");
}
}
class C = A with B; //使用with 关键字,表示 类C 是由 类A 和 类B 混合而构成的
main(){
C c = new C();
C.a(); // 这是 A 的 a 方法
C.b(); // 这是 B 的 b 方法
}
2.7.7 静态成员变量和静态成员方法
class Cons {
static const name = "张三";
static sayHello(){
print("hello, 这是 ${Cons.name}");
}
}
main(){
Cons.sayHello(); // hello, 这是 张三
print(Cons.name);//张三
}
2.8 异步
2.9 关键字
- with 提供类的方法给其他类使用,当属性和方法重复时,以当前类为准
第3节 依赖管理
库:Libraries, Dart提供了很多功能库,只需要导入对应包即可
1.导入功能包
import 'dart:html';
2.引用其他.dart文件
使用相对路径引用:./ 或 ../
util.dart文件:
int add(int a, int b){
return a + b;
}
demo.dart文件
import './util.dart' //俩文件在同一目录下
main(){
print(add(1,2));
}
3.为导入的包设置一个别名
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2; // 使用 as 关键字 为包设置一个别名
// lib1 包中的 元素
Element element1 = Element();
// lib2 包中的元素
lib2.Element element2 = lib2.Element();
4.导入包中的部分功能
import 'package:lib1/lib1.dart' show foo; // 只导入lib1包中的 foo
import 'package:lib1/lib1.dart' hide foo; // 导入除了foo的所有其他部分
5.懒加载导入包
import 'package:greetings/hello.dart' deferred as hello; // 使用 deferred as 让hello包在使用时才加载
附录
参考
- flutter Dart语法
- flutter 实战
常用网址
- Flutter中文网
- 掘金Flutter社区