Flutter for OpenHarmony:Dart 语法入门(中)附鸿蒙flutter演示
本文系统介绍了Dart语言核心语法及其在Flutter开发中的应用。主要内容包括:1)函数基础(定义调用、匿名函数、箭头函数、参数类型);2)集合类型(List、Map、Set的操作与转换);3)面向对象编程(类与对象、继承、方法重写)。通过学生信息管理案例,展示了如何将Dart语法与Flutter组件开发结合,包括数据操作、页面构建和类设计。文章强调语法是工具,最终目的是解决实际问题,为Flut
目录
一、函数(Flutter 组件开发基础)
函数是封装可复用代码的最小单元,Flutter 中自定义组件、处理逻辑都离不开函数。
1. 函数的定义与调用
// 函数格式:返回值类型 函数名(参数类型 参数名) { 函数体 }
// 示例:定义一个计算两数之和的函数
int add(int num1, int num2) {
int result = num1 + num2;
return result; // 返回计算结果
}
// 无返回值函数,这里没有写返回类型,编译器会推成dynamic类型
printInfo(String name) {
print("姓名:$name");
}
void main() {
// 调用函数:函数名(参数值)
int sum = add(5, 3);
print("和为:$sum"); // 输出:和为:8
printInfo("李四"); // 输出:姓名:李四
}
注:省略返回值类型,Dart 会自动推断,但推荐显式声明,代码更清晰。
2. Dart 特色函数
(1)匿名函数
匿名函数就是 “没有名字的函数”,它的核心作用是 “临时用一次”,不用单独定义函数名,尤其适合作为参数传递给其他函数(比如集合的遍历、按钮的点击回调)。
void main() {
List<int> nums = [1,2,3,4];
// 匿名函数作为forEach的参数
nums.forEach((int num) {
print("数字:$num,平方:${num*num}");
});
// 省略参数类型,Dart自动推断
nums.forEach((num) {
print("数字:$num,立方:${num*num*num}");
});
}
(2)箭头函数
当函数体只有一行代码时,可用箭头函数 => 简化。
void main() {
// 普通函数
int multiply(int a, int b) {
return a * b;
}
// 箭头函数(等价于上面的函数)
int multiply2(int a, int b) => a * b;
print(multiply2(4,5)); // 输出:20
// Flutter实战场景:构建Text组件的箭头函数
Widget getTextWidget(String content) => Text(
content,
style: TextStyle(fontSize: 16),
);
}
注意:箭头函数后只能跟一行代码,不能加
{},也不能加return,会自动隐含。
(3)参数类型:必选参数 / 可选参数
Flutter 中所有组件的参数都是 “可选命名参数”,比如 Text("文本", style: TextStyle()),这是 Dart 函数参数的核心设计,所以这个必须掌握。
| 参数类型 | 语法 | 示例 | Flutter 应用 |
| 必选参数 | 直接写参数 | add(int a, int b) | 函数必须传的核心参数 |
| 可选位置参数 | 用 [] 包裹 |
sayHello(String name, [int? age]) | 非核心参数,按位置传 |
| 可选命名参数 | 用 {} 包裹 |
sayHi({String? name, int? age}) | 所有 Flutter 组件参数 |
// 1. 可选位置参数(按位置传参,可省略)
String sayHello(String name, [int? age]) {
if (age == null) {
return "你好,$name!";
} else {
return "你好,$name!年龄:$age";
}
}
// 2. 可选命名参数(按名称传参,顺序无关)
String sayHi({String? name, int? age}) {
return "Hi~ ${name ?? '匿名用户'} ${age != null ? '(' + age.toString() + '岁)' : ''}";
}
// 3. required关键字(强制传命名参数)
String sayGoodbye({required String name}) {
return "再见,$name!";
}
void main() {
print(sayHello("小明")); // 输出:你好,小明!
print(sayHello("小红", 18)); // 输出:你好,小红!年龄:18
print(sayHi(name: "小李")); // 输出:Hi~ 小李
print(sayHi(age: 20, name: "小王")); // 输出:Hi~ 小王 (20岁)
print(sayGoodbye(name: "小张")); // 必须传name,否则报错
// print(sayGoodbye()); // 报错:缺少required参数name
}
Flutter 写 Text 组件时,"Hello Flutter" 是必选位置参数(必须传,否则不知道显示什么),而 style:、textAlign: 是可选命名参数(可传可不传,不传就用默认样式);required 关键字则用于 “自定义 Widget 时,强制调用者传某个参数”,比如你写一个 “用户卡片 Widget”,必须传用户姓名,就可以用 required String name。
Text(
"Hello Flutter", // 必选参数(第一个位置参数)
style: TextStyle(fontSize: 20), // 可选命名参数
textAlign: TextAlign.center, // 可选命名参数
);
二、集合类型
Dart 有三种核心集合:List(列表)、Map(键值对)、Set(无重复集合)
1. List(列表,等价于其他语言的数组)
List 是有序、可重复的集合,最大特点是 “通过索引取值”(比如 fruits[0] 取第一个元素),这也是 Flutter 中 ListView、GridView 渲染列表的核心数据来源——你后端接口返回的 “商品列表”,本质就是一个 List,每个元素是一个商品的信息(Map 类型)。
void main() {
// 1. 声明List
// 方式1:指定类型,避免存错数据类型
List<String> fruits = ["苹果", "香蕉", "橙子"];
// 方式2:空List,之后动态添加数据
List<int> nums = [];
// 2. 常用操作
fruits.add("葡萄"); // 添加元素:["苹果","香蕉","橙子","葡萄"]
fruits.insert(1, "草莓"); // 插入元素:["苹果","草莓","香蕉","橙子","葡萄"]
fruits.remove("香蕉"); // 删除元素:["苹果","草莓","橙子","葡萄"]
print(fruits[0]); // 取值:苹果
print(fruits.length); // 长度:4
// 3. 遍历+转换(Flutter中最核心的用法)
// 将List<String>转为List<Widget>
List<Widget> fruitWidgets = fruits.map((fruit) {
// 对遍历到的每一个 fruit(单个水果名称),返回一个 Text 组件
return Text(fruit);
}).toList();// 4. 把 map 生成的迭代器转换成真正的 List 列表(关键!map 本身不是列表)
print(fruitWidgets); // 输出:[Text("苹果"), Text("草莓"), ...]
}
注:
add/insert/remove是 “修改 List” 的基础操作,对应 Flutter 中 “下拉加载更多”(add)、“插入新数据”(insert)、“删除列表项”(remove)的业务场景;map()是 Flutter 中 “数据转 Widget” 的核心方法 —— 后端返回的是 “数据 List”,你需要把每个数据转换成一个 Widget(比如 Text、Container),再用toList()转成 Widget List,才能给 ListView 渲染。
2. Map(键值对)
Map 是无序、键唯一的键值对集合,核心特点是 “通过键取值”(比如 user["name"]),这是解析后端 JSON 数据的 “标配”—— 后端返回的几乎所有 JSON 数据,在 Dart 中都会被解析成 Map 类型(比如 {"name":"张三","age":25})。
void main() {
// 1. 声明Map(键,值)
Map<String, dynamic> user = {
"name": "张三",
"age": 25,
"isVip": true,
"hobbies": ["打球", "编程"]
};
// 2. 常用操作
print(user["name"]); // 取值:张三
user["age"] = 26; // 修改值
user["address"] = "北京"; // 添加新键值对
user.remove("isVip"); // 删除键值对
// 3. 遍历Map
user.forEach((key, value) {
print("$key:$value");
});
}
注:Map 的键(key)必须是唯一的,比如不能同时有两个 "name" 键。
3. Set(无重复集合)
Set 是无序、元素唯一的集合,核心作用是 “去重”,比如你有一个 “用户标签 List”,里面有重复的标签,用 Set 转换一下就能自动去重,适合 “筛选不重复数据” 的场景。
void main() {
Set<int> nums = {1,2,2,3,3,3};
print(nums); // 自动去重:{1,2,3}
nums.add(4); // 添加元素
nums.add(2); // 重复元素,不生效
print(nums); // {1,2,3,4}
}
三、面向对象
Dart 是纯面向对象语言,所有东西都是对象(包括数字、函数),而 Flutter 中所有 Widget(比如 Text、Container)都是 “类的实例”,自定义 Widget 本质就是 “定义一个类,继承StatelessWidget 或者 StatefulWidget”,所以我们必须理解 “类、对象、继承” 。
1. 类与对象
类是 “模板”,对象是 “根据模板创建的具体实例”—— 比如 Person 类是 “人的模板”,包含姓名、年龄等属性,以及打招呼的方法;p1 是 “张三这个具体的人”,是 Person 类的一个对象。
//格式
class 类名{
成员变量
成员函数
}
// 定义类:类名首字母大写(大驼峰规则,Flutter所有Widget都遵循)
class Person {
// 类的属性(成员变量):对应“人的特征”
String name;
int age;
// 构造函数:创建对象时初始化属性,这是简化的写法
Person(this.name, this.age);
// 类的方法(成员函数):对应“人的行为”
void sayHello() {
print("我是$name,今年$age岁!");
}
// 带返回值的方法:返回“人的信息字符串”
String getInfo() {
return "姓名:$name,年龄:$age";
}
}
void main() {
// 创建对象:类名(参数) → 根据模板创建具体实例
Person p1 = Person("张三", 25);
// 调用方法:对象.方法名()
p1.sayHello(); // 输出:我是张三,今年25岁!
print(p1.getInfo()); // 输出:姓名:张三,年龄:25
// 访问属性:对象.属性名
print(p1.name); // 输出:张三
p1.age = 26; // 修改属性
p1.sayHello(); // 输出:我是张三,今年26岁!
}
2. 继承(extends)
继承是 “子类可以直接用父类的属性和方法”,还可以新增自己的属性 / 方法,或重写父类的方法。Flutter 中所有 Widget 都继承自 Widget 类。
关键字:extends
使用super可以调用父类的内容
// 父类:Person(基础模板)
class Person {
String name;
int age;
Person(this.name, this.age);
void sayHello() {
print("我是$name,今年$age岁!");
}
}
// 子类:Student(继承Person,新增“班级”属性)
class Student extends Person {
// 子类新增属性:学生特有的“班级”
String className;
// 子类构造函数:super调用父类构造函数(必须)
Student(String name, int age, this.className) : super(name, age);
// 重写父类方法:@override注解(可选,但推荐加,代码更清晰)
@override
void sayHello() {
// 调用父类方法(可选,保留父类逻辑)
super.sayHello();
// 新增子类逻辑:学生特有的打招呼内容
print("我是$className的学生!");
}
// 子类新增方法:学生特有的“学习”行为
void study() {
print("$name在$className学习!");
}
}
void main() {
Student s = Student("小红", 18, "三年二班");
s.sayHello();
// 输出:
// 我是小红,今年18岁!(父类方法)
// 我是三年二班的学生!(子类新增逻辑)
s.study(); // 输出:小红在三年二班学习!(子类新增方法)
}
- 类的构造函数参数的简化写法必须用
this.属性名,比如Person(this.name, this.age),否则属性不会被初始化。- 如果父类的构造函数需要传入参数,则继承时必须用
super调用父类构造函数并传参;子类构造函数的函数体第一句必须写: super(父类参数),比如Student(name, age, className) : super(name, age)。
四、flutter实战
现在看不懂具体每行代码干什么没关系,下面会讲一下大致流程,能明白大致流程就行。
将下面的代码复制粘贴到main.dart文件中,保存一下,然后使用鸿蒙模拟器运行即可。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dart 核心语法实战',
theme: ThemeData(primarySwatch: Colors.blue),
home: const StudentManagerPage(),
);
}
}
// 页面组件:学生信息管理页
class StudentManagerPage extends StatefulWidget {
const StudentManagerPage({super.key});
@override
State<StudentManagerPage> createState() => _StudentManagerPageState();
}
class _StudentManagerPageState extends State<StudentManagerPage> {
// 1. 集合知识点:List(存储学生列表)、Set(存储去重标签)、Map(存储示例用户)
final List<Student> _studentList = [];
final Set<String> _tagSet = {"学生", "在校", "青年"}; // 初始标签(Set自动去重)
final Map<String, dynamic> _demoUser = {
// Map:模拟接口返回的用户数据
"name": "默认学生",
"age": 18,
"className": "高一(1)班",
"tags": ["学习", "运动", "阅读"]
};
/// 构建用户信息字符串
/// [name]:必填,[age]:可选,[className]:可选
String buildUserInfo({
required String name,
int? age,
String? className,
}) {
// 空安全处理
String ageStr = age?.toString() ?? "未知";
String classStr = className ?? "未分班";
return "姓名:$name,年龄:$ageStr,班级:$classStr";
}
// 3. 函数知识点:箭头函数
/// 生成默认学生(箭头函数,返回Student对象)
Student _generateDefaultStudent() => Student(
_demoUser["name"],
_demoUser["age"],
_demoUser["className"],
);
// 4. 业务方法:添加学生
void _addStudent() {
setState(() {
final newStudent = _generateDefaultStudent();
_studentList.add(newStudent);
// Set去重:添加重复标签不会生效
_tagSet.addAll(_demoUser["tags"]);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("学生信息管理")),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 按钮:添加学生
ElevatedButton(
onPressed: () {
// 匿名函数:按钮点击事件
_addStudent();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("添加学生成功!")),
);
},
child: const Text("添加默认学生"),
),
const SizedBox(height: 20),
// 展示去重标签(Set转List,map转换为Widget)
const Text("学生标签(Set去重):"),
Wrap(
spacing: 8,
children: _tagSet.map((tag) {
// List.map转换Widget(核心知识点)
return Chip(label: Text(tag));
}).toList(), // 必须加toList()!
),
const SizedBox(height: 20),
const Text("学生列表:"),
Expanded(
child: _studentList.isEmpty
? const Center(child: Text("暂无学生,点击添加"))
: ListView.builder(
itemCount: _studentList.length,
itemBuilder: (context, index) {
final student = _studentList[index];
// 调用可选参数函数:构建学生信息
final studentInfo = buildUserInfo(
name: student.name,
age: student.age,
className: student.className,
);
return ListTile(
title: Text(studentInfo),
subtitle: Text(student.sayHello()), // 调用类的方法
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
// 匿名函数:删除学生
setState(
() => _studentList.removeAt(index)); // 箭头函数简化
},
),
);
},
),
),
],
),
),
);
}
}
// 面向对象:父类Person
class Person {
String name;
int age;
// 构造函数(Dart简化写法:this.属性)
Person(this.name, this.age);
// 类的方法
String sayHello() {
return "我是$name,今年$age岁";
}
}
// 面向对象:子类Student(继承Person)
class Student extends Person {
String className;
// 子类构造函数:super调用父类构造(必须)
Student(String name, int age, this.className) : super(name, age);
// 重写父类方法
@override
String sayHello() {
// 调用父类方法 + 子类扩展逻辑
return "${super.sayHello()},就读于$className";
}
// 子类新增方法
void study() {
print("$name在$className学习!");
}
}
整个代码大致可分为三部分:
1. 通过方法操作数据
2. 构建页面
3. 类
我们跟着运行的界面一步步来看


这个界面,因为学生列表为空,使用显示,暂无学生,标签显示的也是标签列表中默认的内容。
然后我们点击页面中的“添加默认学生”按钮

第一步:他会执行点击事件,点击事件是一个匿名函数,函数中干了两件事:1. 添加学生,2. 显示消息。
第二步:执行添加学生的函数,里面通过_generateDefaultStudent()函数,将Map里面的内容创建成一个学生类对象。添加到学生列表,并将对应的标签添加到标签列表。
第三步:显示一个提示消息,内容是“添加学生成功”。

第四步:将现在标签列表中的标签显示出来。
第五步:先获取学生列表的当前元素,buildUserInfo函数返回一个字符串,把他作为标题。然后输入学生类里面的sayHello方法,显示出来。
第六步:创建一个删除按钮,点击时通过箭头函数将当前元素从列表中移除。
结尾
这个程序中用到很多知识,包括函数、集合、类,大家可以好好看一下这个案例,了解一下它的执行流程。通过这个案例,我们系统地落地了 Dart 语言的核心语法特性,从基础的集合操作(List/Set/Map)、函数用法(可选参数、箭头函数、匿名函数),到面向对象编程(类的继承、方法重写),再到空安全处理等现代 Dart 特性,都在实际的 Flutter 界面开发中得到了体现。
组件的使用看不懂没关系,之后还会学,这个案例的价值不仅在于语法的实践,更在于展示了如何将 Dart 语言特性与 Flutter 组件开发结合。
编程的本质是解决问题,而语法只是工具。希望这个小案例能帮助你打通「语法学习」到「实战应用」的链路,在后续的 Flutter 开发之路上,始终以解决实际业务问题为导向,让每一个语法知识点都能发挥其真正的价值。
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)