淘先锋技术网

首页 1 2 3 4 5 6 7

前言:

前边配置好了环境,接下来学习flutter开发的语言,dart。

一、查看Dart版本

 查看dart位置

 二、创建Dart工程

先来创建个空的

选择工程存放位置。

设置好sdk的位置。 

设置Module名称。

 

打开demo1.dart就可以看到类似OC工程里main文件的文件了。

‘control + r ’   即可运行代码,此时是跑在AS软件里的终端上的,未触发到模拟器上,因为属于一个空工程。

 三、创建flutter工程

这里工程名字注意一下,不可以使用驼峰命名。另外编程语言也是可以选择的,这里使用默认设置,Finish。

进入到开发界面,找到lib下的main.dart。

【扩展】

注意右侧这个竖线,是控制代码行数和分割右侧展示区的线,不习惯的话可以去下图位置去掉勾选。

另外这里可以选择不同语言的每行最大字符数,超过则自动换行。

【扩展完毕】↑ 

 四、语法

回到main.dart文件中。

顶部选择模拟器的选项我们选择Chrome(Web),运行时会自动调起Google浏览器,直接最小化浏览器看AS页面即可。

【tips】web运行的warning

在web作为运行媒介时,可能会报下面这个waring。

我们只需在终端的该工程目录下输入  'flutter create .' 即可

1.var、final、const

void varDemo() {
  //var 声明的是一个变量,可以赋值不同的类型,未初始化则为null
  var a;
  print(a);
  a = "hello world";
  print(a);
  a = 100;
  print(a);

  //final 声明一个只能赋值一次的变量,且不可更改,并且未初始化时不可使用!
  final b;
  //print(b);//这里会报错,b未初始化
  b = "string";
  print(b);

  //const 常量,定义时必须初始化,且不可修改。
  //const c;//这里会报错,const修饰的是一个常量,常量在定义时必须初始化
  const c = 22;
  print(c);
}

 控制台输出结果:

null
hello world
100
string
22

2.数据类型

2.1 数值型Number

包含int,double。

void numDemo() {
  int a;
  a = 10;
  print(a);
  //a = 1.5;//这里a是int类型的,如果赋值double类型数值会报错
  print("-----");

  num b = 11;
  print(b);
  b = 2.2;
  print(b);//num类型包含int和double,不会报错
  print("-----");

  double c = 1.5;
  print(c);
  c = 12;
  print(c);//不报错
  print("-----");

  print(a.isOdd);//判断a是否是奇数
  print(a.isEven);//判断a是否是偶数
  print("-----");

  //算数运算符 + - * / %(取模)  ~/(除以以后取整)
  c = 31;
  print(c~/a);
  print("-----");

  //数据类型转换
  c = 3.1;
  print(c.toInt());//double转int
  print(c.toInt().isOdd);
  print(a.toDouble());
}

控制台输出结果:

10
-----
11
2.2
-----
1.5
12
-----
false
true
-----
3
-----
3
true
10

2.2 字符串String

【Tips】折叠代码段快捷键:command 加上 ‘+’ or '-'

void stringDemo() {
  //Dart中字符串分 单引号 和 双引号,效果是一样的
  var aa = 'hello';
  var bb = "world";
  print(aa + bb);

  //也可以创建String类型变量
  String str = 'Mcl';
  String str1 = 'Mcl' 'hello' 'world';//会自动拼接
  String str2 = 'Mcl\n' 'hello\n' 'world';//会自动拼接,但是换行了
  String str3 = '''Tom  Jerry
  Mark
  Lee
  Lucy''';//3引号字符串,会保留引号间的格式,如空格,回车等
  print(str);
  print(str1);
  print(str2);
  print(str3);

  //取字符串其中的某个字符
  print(str[0]);
  print(str[1]);
  //拼接
  print(str + '!!!');
  //多次重复输出同一字符串
  print(str * 3);//这也太方便了吧哇哈哈
  //带参数输出
  int a = 1;
  int b = 2;
  int c = a + b;
  print('a + b = ${a + b}');//这里注意 ${} 应放到引号内!
  print('a + b = $c');//如果没有表达式只有一个参数则不需要花括号{}

  //转义
  String str4 = 'Tom\nJerry';
  String str5 = r'Tom\nJerry';//引号前加个小写的r
  print(str4);
  print(str5);
  print(str4.length);//回车算一个字符
  print(str5.length);//\n是2个字符,所以比str4长了1
}

 控制台输出结果:

helloworld
Mcl
Mclhelloworld
Mcl
hello
world
Tom  Jerry
  Mark
  Lee
  Lucy
M
c
Mcl!!!
MclMclMcl
a + b = 3
a + b = 3
Tom
Jerry
Tom\nJerry
9
10

2.3 数组List

void listDemo() {
  //Dart中list数组也分两种,可变和不可变
  var list1 = [1,2,3];//可变
  var list2 = const [1,2,3];//元素不可变
  print(list1);
  print(list2);

  //获取list其中某个元素并更改
  print(list1[2]);
  list1[2] = 33;
  print(list1[2]);

  // print(list2[2]);
  // list2[2] = 33;//这里就报错了,因为const修饰,不可修改
  // print(list2[2]);

  //在可变数组中添加元素
  list1.add(5);
  print(list1);
  //指定位置插入元素
  list1.insert(3, 4);
  print(list1);
  //删除某个元素
  list1.remove(33);//这里参数让写object类型,但是写整形也不会报错
  // list1.removeAt(0);//还有其他方法比如删除末位的,删除某个index区间的
  print(list1);
  //清空
  list1.clear();
  print(list1);

  //数组排序
  var list3 = [1, 3, 99, 201, 5, 2, 9, 4, 7];
  print(list3.sublist(2, 7));//输出未排序list3从下标为2开始(包含2的) 到下标为7的值(不包含7的)
  list3.sort();
  print(list3);
  //指定区间内排序并输出
  print(list3.sublist(2, 7));//输出排序后list3从下标为2开始(包含2的) 到下标为7的值(不包含7的)
}

 控制台打印结果:

[1, 2, 3]
[1, 2, 3]
3
33
[1, 2, 33, 5]
[1, 2, 33, 4, 5]
[1, 2, 4, 5]
[]
[99, 201, 5, 2, 9]
[1, 2, 3, 4, 5, 7, 9, 99, 201]
[3, 4, 5, 7, 9]

 2.4 Map(类似OC字典)

void mapDemo() {
  //map是指键值对 分可变和不可变 类似OC中的字典
  var map1 = {'one': 'Tom', 'two': 'Jerry'};
  print(map1);
  map1['two'] = 'Lucy';
  print(map1);
  //不可变的
  var map2 = const {'one': 'Tom1', 'two': 'Jerry1'};
  print(map2);
  // map2['two'] = 'Lucy';//这里会报错,const修饰的map不可修改
  // print(map2);

  //常用方法
  print(map1.length);
  print(map1.values);
  print(map1.keys);

  //map与list的关联
  var list1 = ['Tom', 'Jerry', "Mark"];
  print(list1.asMap());//这里将list转成了map格式,list元素成了map的values,keys则是下标0,1,2
}

控制台输出结果

{one: Tom, two: Jerry}
{one: Tom, two: Lucy}
{one: Tom1, two: Jerry1}
2
(Tom, Lucy)
(one, two)
{0: Tom, 1: Jerry, 2: Mark}

3.Dart特有运算符

??=   和  ??

//操作符
void operatorDemo() {
  //??=  如果左侧为nil则赋值,如果左侧有值则返回左侧值
  var a;
  a ??= 6;
  a ??= 7;
  print(a);//输出6 只赋值一次非空

  //??  如果左侧有值则返回左侧值,如果左侧为空,则返回右侧值
  var b;
  print(b ?? a);//b为空,输出a的值6
  b = 8;
  print(b ?? a);//b不为空,输出b的值8

  //二者都是判断左侧是否为空,非空则取之,空则取右侧值,不过??=涉及到赋值,而??则没有
}

控制台输出结果:

6
6
8

4.方法

4.1 方法&箭头函数

void main() {
  functionDemo();
  functionDemo1();
}
//箭头函数
void functionDemo() {
  /*方法
  * 方法也是一个对象
  * 返回值和参数类型可以省略
  * 当方法执行语句只有一句的时候,可以使用箭头函数 => 表达式,而省略花括号
  * */
  print('hello');
  print(sum(10, 20));
}
void functionDemo1() => print('world');//箭头函数
//正常c函数
int sum (int a, int b) {
  return a + b;
}
//改用箭头函数后 返回值int,参数类型int,以及'return'都可以省略,甚至可以使用三目运算符?:
sum1 (a, b) => a + b;

控制台输出结果:

hello
30
world

4.2 方法&可选参数

/*sum3()中 b和c是可选参数,调用sum3时可以不用填写,
* 并且赋值b和c时可以不考虑顺序,但是必须填写参数名
* b和c的参数类型var可以不写
* */
sum3 (int a, {var b, var c}) {
  b ??= 0;//nil则赋值为0
  c ??= 0;
  return a + b + c;
}
/*sum4()中 b和c也是可选参数,但是赋值b和c时因为是小括号,
* 所以要考虑顺序,但不必填写参数名
* 而b & c如果设定了int类型而不初始化赋值则会报错
* */
sum4 (int a, [int b = 0, int c = 0]) {
  return a + b + c;
}
//如果sum4中b不初始化,可以在int后+问号?,并且在方法中赋值,则不会报错
//int? 称为nullability,告诉编译器进行了后边为空的处理
//这里sum5等同于sum4
sum5 (int a, [int? b, int? c]) {
  b ??= 0;
  c ??= 0;
  return a + b + c;
}

functionDemo2 () {
  sum3(10, c:5, b:4);//输出19
  sum3(10);//输出10

  sum4(10, 4, 5);//输出19
  sum4(10, 4);//输出14 可选不赋值c
  sum5(10, 4, 6);//输出20
  sum5(10, 4);//输出14 可选不赋值c
}

控制台输出functionDemo2()结果:

19
10
19
14
20
14

4.3 方法&方法作为参数传递

void main() {
  functionDemo3();
}
printHello() {
  print('hello');
}
//方法名可以作为参数传递 赋值
void functionDemo3() {
  var hello = printHello;//方法名赋值
  hello();

  var list = [1, 2, 3, 4];

  list.forEach(print);
  //看下forEach的源码
  // void forEach(void f(E element)) {
  //   for (E element in this) f(element);
  // }
  //forEach里的 f == print 这就是参数传递 E是指list
  //那么list.forEach(print)就相当于打印list里的每个元素

  list.forEach(myPrint);

  myForEach(list, print);
  //其实感觉上像是OC里的回调或者block,这边调用一个print or myPrint;
  //那边就执行了myPrint里的具体内容,更像是一个block。
}
//仿写一个list.forEach(print)?
int b = 0;
void myPrint(var a) {
  b++;
  print('元素$b = $a');
  //a就是list里的每个element  myPrint相当于forEach里的f
}

//我们自己写一个forEach怎么写呢?
void myForEach(List list, void func(var element)) {
  for(var e in list) func(e);//为list中的每个值都执行func方法
}

控制台输出结果:

hello
1
2
3
4
元素1 = 1
元素2 = 2
元素3 = 3
元素4 = 4
1
2
3
4

5.匿名函数

void main() {
  functionDemo4();
}
//1.匿名方法:没有方法名的方法
void functionDemo4() {
  //这样写的话,匿名方法无法单独存在,必须赋值给其他变量才能调用
  var func = () {
    print('我是匿名方法');
  };
  func();

  //2.立即执行函数
  (() {
    print('立即执行函数');
  }) ();//前边用小括号包起来,相当于这样()();
  //前一个括号里是匿名函数,后一个括号是方法中包含的0个参数

  //3.匿名方法实例:像刚才我们的 list.forEach(myPrint);
  var list = [1, 2, 3, 4];
  //就可以写成
  int b = 0;
  list.forEach((var a) {
    b++;
    print('元素$b = $a');
  });//forEach里的就是一个匿名函数,这就更像block了。
}

输出结果:

我是匿名方法
立即执行函数
元素1 = 1
元素2 = 2
元素3 = 3
元素4 = 4

6.闭包

void main() {
  closureDemo();//闭包 closure
}
// ---------
//闭包:定义在函数里面的函数,闭包也是一个对象。
//作用:可以访问外部函数的局部变量。
void closureDemo() {
  var func = funcA();
  func();
  func();
  func();
  func();/*4次调用按理说每次调用都会打印0,但结果是0,1,2,3
  *因为func是一个闭包,会一直持有funcA,count不会释放
  */

  var func2 = funcA();
  func2();
  func2();
  func2();
  func2();/*重新赋值以后count就又从0开始了
  *因为func2是一个新的闭包
  */
}
funcA () {
  int count = 0;
  return () => print(count++);//返回一个匿名函数
}

输出结果:

0
1
2
3
0
1
2
3

总结:

至此,关于Dart的基础语法就简单介绍到这里~只是很基础的了解了下,其中还有很多额外的用法,我们以后再探索~