Flutter从入门到实战
一共分为23个系列
①(Flutter、Dart环境搭建篇) 共3个内容 已更新
②(Dart语法1 篇) 共4个内容 已更新
③(Dart语法2 篇) 共2个内容 已更新
④(Flutter案例开发篇) 共4个内容 已更新
⑤(Flutter的StatelessWidget 共3个内容 已更新
⑥(Flutter的基础Widget篇) 共2个内容 已更新
⑦(布局Widget篇) 共1个内容 已更新
⑧(Flex、Row、Column以及Flexible、Stack篇) 共1个内容 已更新
⑨(滚动的Widget篇) 共4个内容 已更新
⑩(Dart的Future和网络篇) 共3个内容 已更新
⑪(豆瓣案例-1篇) 共3个内容 已更新
⑫(豆瓣案例-2篇) 共3个内容 已更新
官方文档说明
官方视频教程
Flutter的YouTube视频教程-小部件
②、Dart语法1 篇
前言
我这边学习Dart语言 使用VSCode
VSCode的插件推荐 :
必须安装
《Dart、Flutter》插件、
Code Runner不需要直接点击运行 直接使用右键的Run Code即可以运行项目
①、Dart基础语言
1.Hello World
main函数是dart入口
/**
* 1.main函数是dart入口
* 2.dart 当中 打印信息是引用 print函数
* */
main(List<String> args) {
// List<String> args -> 列表<String> - 泛型
print("hello world");
}
2.声明变量的几种方式
2.1 明确的声明
String name = "宇夜iOS";
int age = 30;
2.2 类型推导
类型推导虽然没有明确的额指定变量的类型,但是变量是有自己的明确的类型
- 使用
var
来声明变量- 使用
final
声明变量- 使用
const
声明变量final
和const
的区别 :
const
必须赋值常量
值(编译期间需要一个确定的值)
final
可以通过计算/函数
取得一个值
(运行期间来确定一个值)
2.2.1 var的声明
var height = 171;
2.2.2 ⭐️ final的声明(开发过程中使用比较多)
// 声明一个日期
final date2 = DateTime.now();
2.3 const的声明
const p = Person("lyh"); // 声明一个人类的对象
const p2 = Person("lyh"); // 声明一个人类的对象
// const 声明的变量 使用 const的构造函数创建 两个对象相等
// 声明一个类
class Person {
final String name;
const Person(this.name);
}
3. 非零即真
main(List<String> args) {
var flag = true;
if (flag) {
print("执行代码");
}
}
4. 字符串类型
4.1 定义字符串的三种方式
4.1.1 定义字符串的方式1 - 单引号'xxx'
var str1 = 'abc';
4.1.2 定义字符串的方式2 - 双引号"xxx"
var str2 = "abc";
4.1.3 定义字符串的方式3 - 多引号"""xxx"""
var str3 = """abc
cba
nba
""";
4.2 字符串的拼接 - 使用 ${变量}
// 字符串和表达式进行拼接
var name = "yh";
var age = "30";
var height = "171";
var msg = "my name ${name}, age is ${age}, height is ${height}";
var msg2 = " name is ${name}, type is ${name.runtimeType}";
print(msg);
print(msg2);
5. 集合类型
5.1 列表List
[v1,v2,v3]
var names = ["ios", "andorid", "rn", "flutter","ios"];
names.add("python"); // 添加
// names.remove(value); // 删除指定某个值
// names.removeAt(index); // 删除指定索引
5.2 集合 Set
{vlaue1,vlaue2}
里面的数据不能重复
集合使用最多的就是 去重元素
var movies = {
"开国典礼", "李小龙传奇", "逃学威龙"};
// from 是命名构造函数 传递一个可迭代的参数 返回的是Set 我们需要转换为List 可以通过 toList
// 去重
names = Set<String>.from(names).toList();
print(names); // ios,andorid,rn,flutter,python
5.3 映射Map{"key":vlaue}
var info = {
"name": "lyh", "age": 17};
②、Dart函数的使用
1.函数的基本使用
函数 注意点:
- 返回值的类型是可以省略(开发中不建议)
main(List<String> args) {
}
// 返回值的类型是可以省略(开发中不建议)
int sum(int num1, int num2) {
return num1 + num2;
}
2.函数的参数(1.必选参数 2.可选参数)
可选参数分为2个 位置可选参数、命名可选参数
2.1 函数的必选参数
void sayHello(String name) {
print(name);
}
可选参数的类型作用
- 位置可选参数
传不传都无所谓,但是参数的位置时对应的
实参
和实参
在进行匹配时,是根据位置
的匹配- 命名可选参数
开发经常见到这种写法
名字必须写
顺序随便
写
2.2 函数的可选参数-位置可选参数 []
sayHello2("yh");
// sayHello2("yh", 19, 20.2);
// 其中 name 是必传参数 age和height是可选参数的位置可选参数。 传不传都无所谓
void sayHello2(String name, [int age = 0, double height = 0.0]) {
print(" name ${name} age ${age} height ${height}");
}
2.3 ⭐️函数的可选参数-命名可选参数 {}
(开发经常常见)
// 命名可选参数 名字必须写 顺序随便写
sayHello3("yh", age: 19);
sayHello3("yh", height: 171);
sayHello3("yh", height: 171,age: 30); // 顺序随便写
// 其中 name 是必传参数
void sayHello3(String name, {
int age = 0, double height = 0.0}) {
print(" name ${name} age ${age} height ${height}");
}
3.函数是一等公民 (不带参数)什么是一等公民 可以理解为最重要
3.1 函数可以作为另外一个函数的参数
test(bar); // 执行bar函数
void test(Function foo) {
foo();
}
void bar() {
print("bar函数被调用");
}
3.2 匿名函数
匿名函数的格式
匿名函数 (参数列表) {函数体}
test(() {
print("匿名函数被调用");
return 100;
});
void test(Function foo) {
var result = foo();
print(result); // 100
}
3.3 箭头函数
箭头函数: 条件,
函数体
只有一行
代码
test(() => print("箭头函数被调用"));
void test(Function foo) {
foo();
}
4.函数是一等公民 (带参数
)
4.1 函数(带参数
)可以作为另外一个函数的参数
test((num1, num2) {
return num1 + num2;
});
// int foo(int num1, int num2) 是一个函数表达式
void test(int foo(int num1, int num2)) {
int result = foo(20, 30);
print(result);
}
4.2 将4.1的函数使用typedef
进行一个别名
为什么要使用typedef
因为 int foo(int num1, int num2) 名字太长了
typedef 在这里给函数进行起一个别名 。比如是一个计算的函数
typedef Calculate = int Function(int num1, int num2);
test((num1, num2) {
return num1 + num2;
});
typedef Calculate = int Function(int num1, int num2);
void test(Calculate calc) {
int result = calc(20, 30);
print(result);
}
4.3 将4.2的函数再抽取出来 用来计算两个数的乘法
// demo1 = 是一个返回值为 Calculate定义函数的别名的函数 的变量
// demo1 将20 和 30 代入到 demo里面
var demo1 = demo();
print(demo1(20, 30)); // 20 * 30 = 600
Calculate demo() {
// 匿名函数 执行了 num1 * num2
return (num1, num2) {
return num1 * num2;
};
}
③、Dart特殊运算符
1. 赋值运算符
1.1 ??= 运算符
??=的作用
- 当原来的变量有值时,name ??= 不执行
- 原来的变量为 null,那么将值赋值给这个变量
// ??= : 当原来的变量有值时,name ??= 不执行
// 原来的变量为 null,那么将值赋值给这个变量
// var name = null;
var name = "lyh";
name ??= "lysddd";
print(name);
// 1、 name = lyh 输出 lyh
// 2、name = null 输出 lysddd
1.2 ?? 运算符
?? 的作用
- ??前面的变量有值,那么就用??前面的变量
- ?? 前面的数据为 null,那么就使用后面的值
// ??前面的变量有值,那么就用??前面的变量
// ?? 前面的数据为 null,那么就使用后面的值
// 将name1 赋值给别人
var name1 = null;
// name1 = "gg";
var temp = name1 ?? "lysddd";
print(temp);
// 1.name1 = null 输出 lysddd
// 2. name = gg 输出 gg
2. 级联运算符
// 普通调用函数
var p = Person();
p.name = "lyh";
p.run();
p.eat();
// 级联运算符调用
var p1 = Person()
..name = "yh"
..eat()
..run();
// 一行代码执行
var p1 = Person()..name = "yh"..eat()..run();
// 声明一个类
class Person {
String name = "";
void run() {
print("runiing");
}
void eat() {
print("eatiing");
}
}
3. for循环运算符
3.1 基础for循环
for (var i = 0; i < 10; i++) {
print(i);
}
3.2 遍历数组
var names = ["yh", "cba", "nba"];
for (var i = 0; i < names.length; i++) {
print(names[i]);
}
3.3 for in
var names = ["yh", "cba", "nba"];
for (var name in names) {
print(name);
}
④、Dart的面向对象
1.类的定义
// var p = Person(); 如果有构造函数 默认的构造函数会被覆盖掉 。这里就会报错
// 使用类的构造函数 快速创建一个类的对象
var p = Person("yh", 17);
class Person {
String name = "";
int age = 18;
// 定义一个构造函数 覆盖了系统默认的构造函数
// Person(String name, int age) {
// this.name = name;
// this.age = age;
// }
// 语法糖 等价于上面的函数
Person(this.name, this.age);
}
2.类的构造函数
2.1 命名构造函数 因为类没有重载,不能编写两个构造函数,延伸出来一个命名构造函数
类没有重载 所以不能同时编写构造两个函数
// 命名构造函数调用
var p = Person.withNameAgeHeight("yh", 19, 2.2);
// fromMap调用
var p2 = Person.fromMap({
"name": "lyh", "age": 19, "height": 1.88});
print(p2); // 可以重写tostring方法 打印类的属性信息
class Person {
String name = "";
int age = 18;
double height = 1.88;
// 不能同时编写两个构造函数 因为类没有重载。 只能使用命名构造函数来完成这个操作
// Person(this.name, this.age);
// Person(this.name, this.age,this.height);
// 命名构造函数
Person.withNameAgeHeight(this.name, this.age, this.height);
// dynamic 任意类型
Person.fromMap(Map<String, dynamic> map) {
this.name = map["name"];
this.age = map["age"];
this.height = map["height"];
}
}
// 重载tostrong方法
@override
String toString() {
// TODO: implement toString
return "$name $age $height";
}
3.Object 和 dynamic的区别
3.1 Object
Object 调用方法时,编译器会报错
Object obj = "yh";
print(obj.substring(1)); // 会报错
3.2 dynamic
dynamic 调用方法时,编译不报错,但是运行时存在安全隐患
dynamic obj1 = "yh";
print(obj1.substring(1));
4.类的初始化列表
var p = Person("yh", age: 10);
print(p.age);
const temp = 20;
class Person {
final String name;
final int age;
// 初始化列表 可以给初始化值
Person(this.name, {
required int age}) : this.age = temp > 20 ? 30 : 50 {
}