feat:更新文档架构

This commit is contained in:
2026-05-20 11:26:38 +08:00
parent ad9a4d6806
commit 8c9b3adc57
46 changed files with 218 additions and 75 deletions

View File

@@ -0,0 +1,377 @@
---
title: Dart基础教程
date: 2025-12-05
---
# 一、基础语法
## 1.1 变量与常量
```dart
// 显式声明类型
String name = 'Dart';
int age = 10;
// 类型推断(使用 var
var city = 'Beijing'; // 自动推断为 String
var count = 100; // 自动推断为 int
// 延迟初始化
String? email; // 可空类型
late String description; // 延迟初始化
const PI = 3.14159;
const List<int> nums = [1, 2, 3]; // 不可修改的列表
final currentTime = DateTime.now(); // 运行时才知道值
final List<int> numbers = [1, 2, 3];
numbers.add(4); // 可以!列表内容可修改
dynamic value = 'Hello';
value = 123; // 可以
value = true; // 可以
// 非空类型(默认)
String name = 'Dart';
// name = null; // 错误!
// 可空类型(使用 ?
String? nickname;
nickname = null; // 正确
// 空值断言(!
String? value = 'Hello';
print(value!.length); // 确信不为null时使用
// 空值合并运算符(??
String? name;
String displayName = name ?? 'Guest'; // name为null时使用'Guest'
// 条件访问(?.
String? text;
print(text?.length); // text为null时返回null不报错
```
&emsp;&emsp;const常量值在编译期就确定对象及其内容都不可变。
&emsp;&emsp;final常量值在运行时确定但只能赋值一次引用不可变但对象内容可能可变。
## 1.2 数据类型
```dart
// 单引号或双引号
String str1 = 'Hello';
String str2 = "World";
// 字符串插值
String name = 'Dart';
int version = 3;
print('$name $version');
print('${name version}');
// int - 整数
int count = 10;
int hex = 0xDEADBEEF;
// double - 浮点数
double price = 19.99;
double exponent = 1.42e5; // 科学计数法
// num - int 和 double 的父类
num value1 = 10;
num value2 = 10.5;
// 常用方法
int a = 5;
double b = 3.14159;
print(b.toStringAsFixed(2)); // 3.14
print(int.parse('42')); // 字符串转int
print(double.parse('3.14')); // 字符串转double
bool isActive = true;
bool isCompleted = false;
// 创建列表
List<int> numbers = [1, 2, 3, 4, 5];
var fruits = ['apple', 'banana', 'orange'];
// 访问元素
print(numbers[0]); // 1
print(numbers.length); // 5
// 添加元素
numbers.add(6);
numbers.addAll([7, 8, 9]);
// 删除元素
numbers.remove(3); // 删除值为3的元素
numbers.removeAt(0); // 删除索引0的元素
// 常用方法
print(numbers.first); // 第一个元素
print(numbers.last); // 最后一个元素
print(numbers.isEmpty); // 是否为空
numbers.forEach((num) => print(num)); // 遍历
// 不可变列表
const fixedList = [1, 2, 3];
// 扩展运算符
var list1 = [1, 2, 3];
var list2 = [0, ...list1]; // [0, 1, 2, 3]
// 创建 Map
Map<String, int> ages = {
'Alice': 25,
'Bob': 30,
'Charlie': 35
};
// 访问元素
print(ages['Alice']); // 25
// 添加/修改元素
ages['David'] = 28;
ages['Alice'] = 26;
// 删除元素
ages.remove('Bob');
// 常用方法
print(ages.keys); // 所有键
print(ages.values); // 所有值
print(ages.length); // 元素个数
print(ages.isEmpty); // 是否为空
print(ages.containsKey('Alice')); // 是否包含键
// 遍历
ages.forEach((key, value) {
print('$key: $value');
});
```
# 二、函数
```dart
// 简写(箭头函数,适用于单行表达式)
String greet2(String name) => 'Hello, $name!';
// 必传参数
int add(int a, int b) {
return a + b;
}
// 可选位置参数(用 [] 包裹,可提供默认值)
String introduce(String name, [int? age, String city = 'Beijing']) {
if (age != null) {
return '$name, $age years old, from $city';
}
return '$name from $city';
}
// 调用示例
print(introduce('Alice')); // Alice from Beijing
print(introduce('Bob', 25)); // Bob, 25 years old, from Beijing
print(introduce('Charlie', 30, 'Shanghai')); // Charlie, 30 years old, from Shanghai
// 命名参数(用 {} 包裹)
void createUser({
required String name, // required 表示必传
int age = 18, // 有默认值
String? email // 可选可为null
}) {
print('Name: $name, Age: $age, Email: $email');
}
// 调用时使用参数名
createUser(name: 'Alice');
createUser(name: 'Bob', age: 25, email: 'bob@example.com');
// 命名参数的优点:顺序无关,更清晰
void setStyle({String? color, double? size, bool? bold}) {
// ...
}
setStyle(bold: true, color: 'red'); // 顺序可以任意
```
# 三、类
```dart
class BankAccount {
String accountNumber; // 公有属性
double _balance; // 私有属性以_开头
BankAccount(this.accountNumber, this._balance);
// 公有方法
double getBalance() {
return _balance;
}
// 私有方法
void _updateBalance(double amount) {
_balance += amount;
}
void deposit(double amount) {
if (amount > 0) {
_updateBalance(amount);
}
}
// Getter
double get balance => _balance;
// Setter
set balance(double value) {
if (value >= 0) {
_balance = value;
}
}
}
// 使用
var account = BankAccount('123456', 1000);
print(account.balance); // 使用getter1000
account.deposit(500);
print(account.balance); // 1500
account.balance = 2000; // 使用setter
```
# 四、任务
```dart
void eventLoopExample() {
print("主线程开始");
// 微任务
scheduleMicrotask(() {
print("微任务1");
});
// 异步任务
Future.delayed(Duration(seconds: 0), () {
print("异步任务1");
});
// 再次添加微任务
scheduleMicrotask(() {
print("微任务2");
});
print("主线程结束");
}
//输出结果:
主线程开始
主线程结束
微任务1
微任务2
异步任务1
```
&emsp;&emsp;在 Dart 的事件循环中,执行顺序如下:
1. 同步代码:首先执行所有同步代码。
2. 微任务队列:然后依次执行微任务队列中的所有微任务。
3. 事件队列:最后执行事件队列中的异步任务。
# 五、异步编程
```dart
// 1. Future() 构造函数
Future<int> calculateSum(int a, int b) {
return Future(() {
return a + b;
});
}
// 2. Future.value() - 立即完成
Future<String> immediateFuture = Future.value("立即结果");
// 3. Future.error() - 立即失败
Future<void> errorFuture = Future.error("错误信息");
// 4. Future.delayed() - 延迟执行
Future<String> delayedFuture = Future.delayed(
Duration(seconds: 3),
() => "延迟结果"
);
// 5. Future.sync() - 同步执行
Future<int> syncFuture = Future.sync(() => 42);
// 从网络请求
Future<http.Response> fetchUserData() async {
return await http.get(Uri.parse('https://api.example.com/user'));
}
// 文件操作
Future<File> writeToFile(String content) async {
final file = File('data.txt');
return await file.writeAsString(content);
}
```
&emsp;&emsp;其他用法:
```dart
Future<void> processData() async {
try {
print("开始获取数据...");
// 等待第一个 Future
final data1 = await fetchDataFromSource1();
print("数据1: $data1");
// 等待第二个 Future
final data2 = await fetchDataFromSource2();
print("数据2: $data2");
// 处理结果
final result = await processCombinedData(data1, data2);
print("最终结果: $result");
} catch (e) {
print("处理过程中出错: $e");
} finally {
print("清理资源");
}
}
// 1. Future.wait() - 等待所有完成
Future<void> fetchAllData() async {
final futures = [
fetchUserData(),
fetchProductData(),
fetchOrderData(),
];
try {
final results = await Future.wait(futures);
print("所有数据获取完成: $results");
} catch (e) {
print("部分请求失败: $e");
}
}
// 2. Future.any() - 第一个完成
Future<String> getFastestResponse() {
return Future.any([
fetchFromServer1(),
fetchFromServer2(),
fetchFromServer3(),
]);
}
// 3. Future.forEach() - 顺序执行
Future<void> processItems(List<String> items) async {
await Future.forEach(items, (item) async {
await processItem(item);
});
}
// 4. 链式操作
Future<String> complexOperation() {
return authenticateUser()
.then((token) => fetchUserProfile(token))
.then((profile) => updateProfile(profile))
.then((updated) => saveToDatabase(updated))
.then((savedId) => "操作完成ID: $savedId")
.catchError((error) {
// 统一错误处理
print("链式操作失败: $error");
return "默认值";
});
}
```

View File

@@ -0,0 +1,248 @@
---
title: Flutter基础教程
date: 2025-12-05
---
# 应用核心Widget
```dart
// Flutter 应用的入口,配置主题、路由、国际化等。
MaterialApp(
home: HomePage(), // 必需:首页
theme: ThemeData.light(), // 主题
routes: {'/details': (c) => DetailsPage()}, // 路由
debugShowCheckedModeBanner: false, // 隐藏调试条
)
// 页面骨架,包含顶部栏、内容区、悬浮按钮等标准组件。
Scaffold(
appBar: AppBar(title: Text('标题')), // 顶部栏
body: Center(child: Text('内容')), // 主体
floatingActionButton: FloatingActionButton(
onPressed: () {}, // 悬浮按钮
),
drawer: Drawer(child: Text('侧边栏')), // 抽屉
bottomNavigationBar: BottomNavigationBar(
items: [], // 底部导航
),
)
```
# 布局Widget
```dart
Container(
width: 100,
height: 50,
margin: EdgeInsets.all(10), // 外边距
padding: EdgeInsets.all(20), // 内边距
decoration: BoxDecoration(
color: Colors.blue, // 背景色
borderRadius: BorderRadius.circular(10), // 圆角
border: Border.all(color: Colors.black), // 边框
),
child: Text('内容'),
)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // 主轴对齐
crossAxisAlignment: CrossAxisAlignment.center, // 交叉轴对齐
children: [Text('左'),Text('中'),Text('右')],
)
Column(
children: [
Expanded(child: Container(color: Colors.red)), // 扩展
Flexible(child: Container(color: Colors.blue)), // 灵活
],
)
// 层叠布局,用于重叠显示 Widget配合 Positioned 定位。
Stack(
children: [
Container(color: Colors.red, width: 200, height: 200), // 底层
Positioned( // 绝对定位
top: 20,
left: 20,
child: Text('重叠内容'),
),
],
)
Row(
children: [
Text('左'),
Spacer(), // 自动占据剩余空间
Text('右'),
],
)
Row(
children: [
Expanded(
flex: 2, // 权重
child: Container(color: Colors.red),
),
Expanded(
flex: 1,
child: Container(color: Colors.blue),
),
],
)
```
# 列表和网格
```dart
ListView(
children: List.generate(20, (i) => ListTile(
title: Text('项目 $i'), // 列表项
)),
)
// 懒加载版本(推荐)
ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) => ListTile(
title: Text('项目 $index'),
),
)
GridView.count(
crossAxisCount: 2, // 每行数量
children: List.generate(20, (i) => Container(
color: Colors.blue,
child: Center(child: Text('$i')),
)),
)
```
# 展示 Widget
```dart
Text(
'Hello Flutter',
style: TextStyle(
fontSize: 20,
color: Colors.blue,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
)
Image.network(
'https://example.com/image.jpg',
width: 100,
height: 100,
fit: BoxFit.cover, // 填充方式
loadingBuilder: (c, child, progress) {
if (progress == null) return child;
return CircularProgressIndicator();
},
)
Icon(
Icons.favorite,
color: Colors.red,
size: 30,
)
```
# 对话框Widget
```dart
// 提示对话框showDialog 显示,需要 context。
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('提示'),
content: Text('确定删除吗?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('确定'),
),
],
),
)
// 底部弹出表单
showModalBottomSheet(
context: context,
builder: (context) => Container(
height: 200,
child: ListView(
children: [],
),
),
)
// 底部轻提示,不打断用户操作
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('操作成功'),
action: SnackBarAction(
label: '撤销',
onPressed: () {},
),
duration: Duration(seconds: 2),
),
)
```
# 导航和路由
```dart
Navigator.push( // 跳转
context,
MaterialPageRoute(builder: (c) => DetailsPage()),
);
Navigator.pop(context); // 返回
Navigator.pushNamed(context, '/details'); // 命名路由
// 页面切换器
PageView(
children: [
Page1(),
Page2(),
Page3(),
],
controller: PageController(),
onPageChanged: (index) => print('切换到 $index'),
)
```
# 手势Widget
```dart
GestureDetector(
onTap: () => print('点击'),
onDoubleTap: () => print('双击'),
onLongPress: () => print('长按'),
onPanUpdate: (details) => print('拖拽: ${details.delta}'),
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
)
InkWell(
onTap: () => print('点击'),
splashColor: Colors.blue.withOpacity(0.3), // 水波纹颜色
child: Container(
padding: EdgeInsets.all(20),
child: Text('可点击区域'),
),
)
```
# 其他Widget
```dart
// 控制 Widget 显示/隐藏,比条件渲染性能更好。
Visibility(
visible: isVisible, // 是否显示
child: Text('内容'),
maintainSize: true, // 保持占位
maintainAnimation: true,
maintainState: true,
)
```

View File

@@ -0,0 +1,29 @@
---
title: Flutter简介与安装
date: 2026-05-02
---
# 一、简介
&emsp;&emsp;Flutter 是 Google 推出的跨平台 UI 开发框架,使用 Dart 语言,通过自带的渲染引擎直接绘制界面,可一套代码同时构建 iOS、Android、Web 及 Windows/macOS/Linux 桌面应用,具备原生级性能、热重载和高 UI 一致性,适合追求多端统一与体验效率的项目开发。
# 二、安装
## 2.1 下载SDK
&emsp;&emsp;打开[官网](https://docs.flutter.dev/install/archive)选择SDK版本下载然后解压到相应目录。
## 2.2 环境变量配置
1. 在系统变量->path中添加'/path/to/flutter/bin'
2. 在系统变量中添加: 'PUB_HOSTED_URL'->'https://pub.flutter-io.cn'
3. 在系统变量中添加: 'FLUTTER_STORAGE_BASE_URL'->'https://storage.flutter-io.cn'
4. 在系统变量中添加: 'FLUTTER_GIT_URL'->'https://gitee.com/mirrors/Flutter.git'
## 2.3 校验安装
&emsp;&emsp;输入`flutter --version``flutter doctor`查看是否有错误输出。
::: tip
Windows开发需要安装Visual Studio的'C++的桌面开发'。
Android开发需要安装Android SDK。
Web开发需要安装Chrome浏览器。
:::
## 三、Android Studio
1. 安装Flutter和Dart插件
2. 在Settings->Languages->Dart中选择Dart路径`/path/to/flutter/bin/cache/dart-sdk`

View File

@@ -0,0 +1,77 @@
---
title: 实战技巧
date: 2025-12-03
---
# 安卓签名
&emsp;&emsp;每次安装/升级软件必须使用同一个签名,否则会将本地数据全部清空。
## 1. 生成密钥库文件
&emsp;&emsp;使用keytool命令生成
```cmd
keytool -genkey -v -keystore android/app/my-release-key.keystore -alias my-key -keyalg RSA -keysize 2048 -validity 10000
```
&emsp;&emsp;根据提示输入相应信息。
&emsp;&emsp;my.keystore为自定义名称。生成后的文件位于android/app/文件夹内
## 2. 配置key.properties
&emsp;&emsp;在android文件夹内新建key.properties文件并配置信息
```properties
# 密钥库文件的密码
storePassword=12345678
# 密钥本身的密码
keyPassword=12345678
# 密钥的别名,在密钥库中标识具体的密钥
keyAlias=my-key
# 密钥库文件相对于本配置文件的路径
storeFile=my-release-key.keystore
```
## 3. 配置build.gradle.kts
```kts
import java.util.Properties
import java.io.FileInputStream
// 从根路径加载密钥属性
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
```
&emsp;&emsp;在android块内新增签名配置
```kts
android {
// 签名配置
signingConfigs {
create("release") {
if (keystorePropertiesFile.exists()) {
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
}
}
}
buildTypes {
release {
signingConfig = if (keystorePropertiesFile.exists()) {
// 使用发布签名
signingConfigs.getByName("release")
} else {
// 使用默认签名
signingConfigs.getByName("debug")
}
}
}
}
```
&emsp;&emsp;打包为release包时即可生效签名。
::: danger
禁止将签名文件上传到Git仓库中。
:::

10
docs/Web/Flutter/index.md Normal file
View File

@@ -0,0 +1,10 @@
---
layout: doc
title: Flutter
---
<script setup>
import { routers } from '../.vitepress/theme/router'
</script>
<MenuList :routers=routers[3] />