该部分内容主要分为四部分, 认真看, 一小时, 带你学完Dart基础语法:
测试工具我选择的是VSCode, 打开空白文件夹开始Dart基础语法的学习吧...
16. mixin混入的使用
- 接口
implements需要将所有的方法都实现一遍, 不管原来的接口类是否实现, mixin混入: 混入类的方法, 只要实现过的, 我都可以拿过来直接用, 比较方便,mixin语法: 定义可混入的类的时候,不用class定义, 需要用mixin定义, 然后通过with进行混入,- 当混入类中的方法 和父类中的方法 以及自己的方法名称相同时 => 优先级:
自己的最高, 混入类的次之, 父类的最低.
void main(List<String> args) {
final sm = SuperMan();
sm.running(); // SuperMan running
sm.flying(); // Flyer flying
sm.eating(); // Person eating
}
mixin Runner {
void running() {
print("Runner running");
}
}
mixin Flyer {
void flying() {
print("Flyer flying");
}
}
class Person {
void eating() {
print("Person eating");
}
void running() {
print("Person running");
}
}
class SuperMan extends Person with Runner, Flyer {
void running() {
print("SuperMan running");
}
}
17. 类属性和类方法
17.1 static 关键字修饰即可
void main(List<String> arguments) {
Person.day = '2023';
print(Person.day); // 2023
Person.running(); // static running
}
class Person {
// 静态属性(类属性)
static String? day;
// 静态方法(类方法)
static void running() {
print("static running");
}
}
对比对象属性(成员变量)和对象方法:
void main(List<String> arguments) {
final p = Person();
p.name = 'zhangsan';
print(p.name); // zhangsan
p.eating(); // zhangsan eating
}
class Person {
// 成员变量
String? name;
// 对象方法
void eating() {
print("$name eating");
}
}
17.2 枚举的定义
// 枚举的定义
enum Colors { red, green, blue }
使用上:
final color = Colors.red;
switch (color) {
case Colors.red:
print("红色");
break;
case Colors.green:
print("绿色");
break;
case Colors.blue:
print("蓝色");
break;
default:
}
// 2.1 获取枚举定义的所有值 => list
print(Colors.values); // [Colors.red, Colors.green, Colors.blue]
// 2.2 获取枚举值所在枚举中的index
print(Colors.blue.index); // 2
18. Dart中库的使用
代码中新建utils 文件夹来演示库的使用:
18.1 Dart 中默认情况下, 一个Dart 文件就是一个模块(库文件)
18.2 引用系统的库: import 'dart: 库的名字':
import 'dart:math';
void main(List<String> arguments) {
final num1 = 20;
final num2 = 21;
print(min(num1, num2)); // 20; 就会引入系统的计算库import 'dart:math';
}
18.3 自定义的库: import '自定义库的相对路径/库的名字':
// math_utils.dart
int sum(int num1, int num2) {
return num1 + num2;
}
import 'dart:math';
import 'utils/math_utils.dart';
void main(List<String> arguments) {
final num1 = 20;
final num2 = 21;
print(sum(num1, num2)); // 41; 就会引入自定义的库import 'utils/math_utils.dart';
}
18.4 当库文件中和当前类中存在同名方法
// math_utils2.dart
int multiply(int num1, int num2) {
return num1 * num2;
}
- 不做处理会报错:
import 'utils/math_utils2.dart';
void main(List<String> arguments) {
final num1 = 20;
final num2 = 21;
// ❌报错: The argument type 'int' can't be assigned to the parameter type 'double'.
print(multiply(num1, num2));
}
double multiply(double num1, double num2) {
return num1 * num2;
}
- 使用as 关键字给库文件起一个别名
import '库的相对路径/库的名字 as 起别名:
import 'utils/math_utils2.dart' as mu2;
void main(List<String> arguments) {
final num1 = 20;
final num2 = 21;
print(mu2.multiply(num1, num2)); // 420
}
18.5 默认情况下, 导入一个库时, 导入的是这个库的全部内容
show: 执行要导入的内容hide: 隐藏某个要导入的内容, 导入其他内容
// math_utils3.dart
int minus(int num1, int num2) {
return num1 - num2;
}
int _privateMinus(int num1, int num2) {
return num1 - num2;
}
double devide(int num1, int num2) {
return num1 / num2;
}
import 'utils/math_utils3.dart' show minus; // 只导入minus, 其他的不导入
import 'utils/math_utils3.dart' hide devide; // 只隐藏devide, 其他的都导入
import 'utils/math_utils3.dart' hide devide, minus; // 可以写多个
18.6 utils 文件夹内有多个库文件, 一一导入太麻烦, 所以只需要创建一个公共头文件utils.dart, 导入进来即可.
utils.dart内部格式为:export '库文件名称';- 外界想使用整个utils 文件夹内的东西, 直接
import 'utils/utils.dart'即可.
18.7 下划线 (_) 开头则表示该标识符在库内是私有的, 同其他语言的private
当属性或者方法前面添加下划线, 就代表私有了, 外界就无法调用了, 就报错了:
void main(List<String> arguments) {
print(_privateMinus(10, 11)); // ❌报错: The function '_privateMinus' isn't defined.
print(minus(5, 1)); // 4
}
18.8 使用第三方的库
flutter 项目创建时候都会 自动创建pubspec.yaml文件, 在练习Dart时, 手动创建测试一下即可.
- 在
pubspec.yaml添加需要以来的第三方库,
# pubspec.yaml
name: dart_learn
description: a libraries
# 添加依赖的第三方库
dependencies:
http: ^0.13.5
# Dart SDK 的 版本
environment:
sdk: '^2.12.0'
- 在pub.dev中搜索需要使用的第三方库, 根据提示, 添加需要依赖的第三方,
- 终端切换至
utils路径下, 执行dart pub get更新代码, 提示Got dependencies!代表着成功了, - 在
math_utils.dart文件中模拟网络请求,
首先要引入头文件,
import 'package:库名/库文件' as 别名
起别名是为了避免想通的sdk名称、方法名等等的冲突.
import 'package:http/http.dart' as http;
void main(List<String> args) async {
var url = 'https://www.wanandroid.com/banner/json';
var response = await http.get(Uri.parse(url));
print("Response status: ${response.statusCode}");
print("Response body: ${response.body}");
/**
* Response status: 200
* Response body: {"data":[{"desc":"我们支持订阅啦~","id":30,
* "imagePath":"https://www.wanandroid.com/blogimgs/42da12d8-de56-4439-b40c-eab66c227a4b.png",
* "isVisible":1,"order":2,"title":"我们支持订阅啦~","type":0,"url":"https://www.wanandroid.com/blog/show/3352"},
* {"desc":"","id":6,"imagePath":"https://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png",
* "isVisible":1,"order":1,"title":"我们新增了一个常用导航Tab~","type":1,"url":"https://www.wanandroid.com/navi"},
* {"desc":"一起来做个App吧","id":10,"imagePath":"https://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png",
* "isVisible":1,"order":1,"title":"一起来做个App吧","type":1,"url":"https://www.wanandroid.com/blog/show/2"}],
* "errorCode":0,"errorMsg":""}
*/
}
19. 断言和懒加载
19.1 断言assert()
- 断言assert() : assert() 的调用将会在生产环境的代码中被忽略掉。
- 在开发过程中,
assert(condition)将会在 条件判断 为false时抛出一个异常。
final num1 = 10;
final num2 = 10;
final num3 = 20;
assert(num1 == num2); // 内部条件为true, 没问题
assert(num1 == num3); // ❌错误: _AssertionError ... Failed assertion: line 14 pos 10: 'num1 == num3': is not true.)
19.2 懒加载
late修饰不为空的变量, 已达到延迟加载的作用;
late String description
- 在使用之前, 必须为其赋值, 不然会报错;
// ❌错误: The late local variable 'description' is definitely unassigned at this point.
print(description);
19.3 库的懒加载
- 使用
deferred as关键字来指定:
import 'dart:math' deferred as math;
等到使用math库中的内容时(math.min(1, 2))即可, 懒加载的最大好处是可以减少APP的启动时间.
19.4 noSuchMethod
- 如果调用了对象上不存在的方法或实例变量将会触发
noSuchMethod方法, - 可以重写
noSuchMethod方法来追踪和记录这一行为.
void main(List<String> arguments) {
var a = A();
a.getInfo();
}
class A implements B {
@override
String get info => throw UnimplementedError();
// Unless you override noSuchMethod, using a
// non-existent member results in a NoSuchMethodError.
@override
// 重写了noSuchMethod
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: '
'${invocation.memberName}');
}
}
class B {
final info = "this is b";
String getInfo() => info;
}
20. 终端创建flutte项目
20.1 终端创建项目和IDE创建项目的区别
终端不会给你创建一堆没用的文件.
20.2 终端创建项目
cd到指定目录flutter create 项目名称- 项目名称
不能包含特殊字符、不能有大写、更不能采用驼峰命名 - 项目名称当由多个单词组成时,
可采用下划线(_)拼接 - 创建
flutter_learn项目
20.3 flutter 项目文件说明
.dart_tool: 记录某些东西(三方库等)的基本信息, 不需要手动配置.idea: 记录项目配置信息的文件, 不需要手动配置lib: 存放所有flutter的源码, 整个flutter项目的入口就是main.dart.metadata: 记录flutter版本信息的, 不需要手动编辑pubspec.yaml: 基本信息和引用说明, 需要手动编辑
20.4 运行一个flutter 项目
- 点击VSCode 右上角
三角号、终端输入flutter run、点击main函数上面的run都能启动程序 - 程序启动后会出现一个工具栏
-
- 闪电标志(hot reload) : 热重载 快捷键: control+F5
-
- 刷新标志(hot restart) : 热重启 快捷键: command+shift+F5
-
- 在使用热重载或者热重启时, 如果代码不生效, 试着检查下代码
是否自动保存了, 没保存的需要保存下. 共有三种方式:
- 在使用热重载或者热重启时, 如果代码不生效, 试着检查下代码
-
- 冷启动, 从0开始, 时间较长, 框架
啥的都从零开始加载 ; - 热重载, 主要执行
build的- 例如: 点击flutter_learn demo, 屏幕中间计数器数字累加, 修改主题颜色, hot reload => 主题颜色会变, 但是计数器数字不变.
- 热重启,
重新运行整个App- 例如: 点击flutter_learn demo, 屏幕中间计数器数字累加, 修改主题颜色, hot restart => 主题颜色会变, 但是计数器数字重置.
20.5 widget
flutter中理解万物都是widget- 当需要传入一个
widget类型时, 传什么都可以, 因为万物都是widget widget释义:- 百度: (不知名的)小器物,小装置,小玩意儿
- 谷歌: 小部件
20.6 Material
- 是一套谷歌的设计风格, 也可说是代码规范, 比如: 文字, 颜色, 排版, 动画, 填充等
flutter高度集成了Material风格的widget
接下来, 就可以进入flutter的开发啦...
结语
路漫漫其修远兮,吾将上下而求索~
.End