Flutter从入门到实战
一共分为23个系列
①(Flutter、Dart环境搭建篇) 共3个内容 已更新
②(Dart语法1 篇) 共4个内容 已更新
③(Dart语法2 篇) 共2个内容 已更新
④(Flutter案例开发篇) 共4个内容 已更新
⑤(Flutter的StatelessWidget 共3个内容 已更新
⑥(Flutter的基础Widget篇) 共2个内容 已更新
⑦(布局Widget篇) 共1个内容 已更新
// 使用构造函数的重定向
var p = Person("yh");
print(p.age);
class Person {
String name;
int age = 199;
// 构造函数 并且给age默认值
// Person(this.name) : age = 10;
// 构造函数的重定向
Person(String name) : this._inernal(name, 20);
Person._inernal(this.name, this.age);
}
基本上只会写一个常量构造函数
因为函数不支持函数重载
使用 const 定义的函数
通过常量构造函数创建出来的对象是相同的
// 使用常量构造函数
const p1 = Person("yh");
const p2 = Person("yh");
const p3 = Person("ys");
print(identical(p1, p2)); // true
print(identical(p1, p3)); // flase
class Person {
final String name;
// final String age;
// 常量构造函数
const Person(this.name);
// const Person(this.name,this.age); // 不支持函数重载
}
工厂构造函数 需要(可以)手动返回一个对象
为什么要什么工厂构造函数 。 因为类无法重载两个构造函数。但是需要满足这个需求就需要到工厂构造函数
因为类无法重载两个构造函数。但是需要满足这个需求就需要到工厂构造函数
class Person {
final String name;
final String color = "red";
// 无法重载两个构造函数 满足不了需求 只能使用工厂构造函数
const Person(this.name);
const Person(this.color);
}
// 使用工厂构造函数 判断2个对象是否为同一个对象
final p1 = Person.withName("yh");
final p2 = Person.withName("yh");
print(identical(p1, p
class Person {
String name = "";
String color = "";
// static 静态 Map 映射
static final Map<String, Person> _nameCache = {};
static final Map<String, Person> _colorCache = {};
// 普通的构造函数:会自动返回创建出来的对象,不能手动的返回
// 工厂构造函数 最大的特点: 可以手动的返回一个对象
// 这个其实是一个缓存机制。多占内存Map。
// 减少创建对象和销毁的过程
factory Person.withName(String name) {
if (_nameCache.containsKey(name)) {
return _nameCache[name]!;
} else {
final p = Person(name, "default");
_nameCache[name] = p;
return p;
}
}
factory Person.withColor(String color) {
if (_colorCache.containsKey(color)) {
return _colorCache[color]!;
} else {
final p = Person("default", color);
_colorCache[color] = p;
return p;
}
}
Person(this.name, this.color);
}
setter 和 getter的作用
设置 和 获取
var p = Person();
// 直接访问属性
p.name = "宇夜iOS";
print(p.name);
// ✨ setter 和 getter的使用
// 通过getter和setter访问
p.setName = "宇夜iOS-1";
print(p.getName);
// 人类
Person {
String name = "";
// setter
// set setName(String name) {
// this.name = name;
// }
// // getter
// String get getName {
// return name;
// }
// 箭头函数的 setter 和 getter
set setName(String name) => this.name = name;
String get getName => name;
}
继承使用关键字
extends
class Animal {
int age;
Animal(this.age);
}
class Person extends Animal {
String name;
// 初始化列表
Person(this.name, int age) : super(age);
}
抽象类
使用 关键字abstract
抽象类
可以没有方法实现\也可以有方法实现- 继承于
抽象类
的类 必须实现抽象类
的方法抽象类
不能实例化
// 第1、2、4点
// Shape 是一个抽象类
// 可以没有方法实现\也可以有方法实现
abstract class Shape {
int getArea();
String getInfo() {
return "形状";
}
// 4.抽象类不能实例化
// factory Shape() {
// return null;
// }
}
// 第3点
// 继承 Shape的抽象类 的类
// 必须重写抽象类的方法
class Recatangle extends Shape {
// 重写
@override
int getArea() {
return 100;
}
}
Map 和 List 抽象类 为什么能实例化
因为 通过工厂构造函数进行实例化
它们有实现吗? 没有 因为使用了external关键字
- external关键字的作用是 : 将方法的声明和方法的实现分离
- 方法的实现 通过一个注解
@patch
去实现- 具体的实现要去看系统的源码了
Map
的实现源码在
4.1 具体看flutter的源码. 在 /Users/liyuhong/development/flutter/bin/cache/dart-sdk/lib/collection
这个就是集合类的源码linked_hash_map.dart
4.2 通过 LinkedHashMap() 进行初始化 最终的实现在 > linked_hash_map.dart
里面实现
最终的代码实现4.3 也可以通过打印runtimeType的真实类型external factory LinkedHashMap( {bool Function(K, K)? equals, int Function(K)? hashCode, bool Function(dynamic)? isValidKey});
print(map.runtimeType); // _InternalLinkedHashMap
// 抽象类 通过工厂构造函数进行实例化
final map = Map();
Dart 中没有哪一个关键字是来定义接口的
没有这些关键字 interface / protocol
默认情况下 所有的类都是隐式接口
Dart支持单继承
当一个类当做接口使用时,那么实现这个接口的类,必须实现这个类
中所有的方法
class Runner {
void running() {}
}
class Flyer {
void flying() {}
}
class Animal {
void eating() {
print("动物吃东西");
}
void running() {
print("running");
}
}
// implements 相当于superMan 要去实现 Runner、Flyer两个类的方法
class superMan extends Animal implements Runner, Flyer {
@override
void edting() {
super.eating();
}
@override
void flying() {}
}
当一个类当做接口使用时,那么实现这个接口的类,不必
实现这个类
中所有的方法
// 混入的使用
final sm = superMan();
sm.running();
sm.flying();
// 输出superMan running、Flyer flying
mixin Runner {
void running() {
print("Runner running");
}
}
mixin Flyer {
void flying() {
print("Flyer flying");
}
}
class Animal {
void eating() {
print("Animal 动物吃东西");
}
void running() {
print("Animal running");
}
}
// 混入的写法: 1.定义可混入的类时,不能用class, mixin
// 2.with进行混入
class superMan extends Animal with Runner, Flyer {
@override
void edting() {
super.eating();
}
void running() {
print("superMan running");
}
}
// 使用
Person.courseTime = "9:00"; // 设置类属性
print(Person.courseTime); // 访问类属性
Person.gotoCourse(); // 调用类方法
;
class Person {
// 成员变量
String name = "";
// 静态属性(类属性)
static String courseTime = "";
// 对象方法
void eating() {
print("eating");
}
// 静态方法(类方法)
static void gotoCourse() {
print("去上课");
}
}
枚举使用关键字
enum
// 使用枚举
final color = Colors.red;
switch (color) {
case Colors.red:
print("红色");
break;
case Colors.blue:
print("蓝色");
break;
case Colors.green:
print("绿色");
break;
}
print(Colors.values);
print(Colors.red.index);
// 定义一个枚举
enum Colors { red, blue, green }
使用
import
关键字导入系统库
// import 'dart:io'; // 文件操作
// import 'dart:isolate'; // 创建线程
// import 'dart:async'; // 异步
import 'dart:math'; // 数学
先定义一些库
比如算数的加减、打印一个日期的库
int sum(num1, num2) {
return num1 + num2;
}
int mul(num1, num2) {
return num1 * num2;
}
int min(int num1, int num2) {
return num1 > num2 ? num1 : num2;
}
String dateFormat() {
return "2020-12-12";
}
import ‘utils/utils.dart’; // 其中utils是一个文件夹
import 'utils/utils.dart';
void main(List<String> args) {
print(sum(20, 30));
print(mul(20, 30));
print(dateFormat());
print(min(20, 30));
}
定义一个库文件 把所有的自定义库引入进来
// 多个库的导入
export 'math_utils.dart';
export 'date_utils.dart';
通过 pub.dev网站查找第三方库
并且创建一个pubspec.yaml
文件
并且设置几个参数
- name: xxx
我这里填写我的名字 yhios
- descreption: xxx
这里填写描述 a dart library
- dependencies: xxx
这里填写 第三方库的安装指令 -- http: ^0.13.4
然后去 pub.dev 去查找库
填写pubspec.yaml
参数 并且安装第三方库
pubspec.yaml
文件的第三方库信息name: yhios
descreption: a dart library
dependencies:
http: ^0.13.4
pub get
或者
dart get
拷贝一份相同的代码 快捷键
shift + option + ↓