前言:
前边配置好了环境,接下来学习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的基础语法就简单介绍到这里~只是很基础的了解了下,其中还有很多额外的用法,我们以后再探索~