Flutter 鸿蒙:利用三方库构建待办清单
本教程面向鸿蒙开发新手,专注讲解Flutter + 三方库 + 鸿蒙跨端开发完整实践。我们将通过开发一个可持久化存储的待办清单应用,从零学习项目创建、三方库集成、代码编写、鸿蒙适配与真机运行,让你快速掌握 Flutter 开发鸿蒙应用的核心流程。项目核心:使用 Flutter 跨端框架 +三方库,实现支持鸿蒙 6.0+(API 20+)的原生体验待办 APP,关闭重启数据不丢失。Flutter 与
Flutter 鸿蒙:利用三方库构建待办清单
Flutter 开发实战:利用三方库构建鸿蒙原生体验的待办清单
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
一、教程简介
本教程面向鸿蒙开发新手,专注讲解 Flutter + 三方库 + 鸿蒙 跨端开发完整实践。我们将通过开发一个可持久化存储的待办清单应用,从零学习项目创建、三方库集成、代码编写、鸿蒙适配与真机运行,让你快速掌握 Flutter 开发鸿蒙应用的核心流程。
项目核心:使用 Flutter 跨端框架 + shared_preferences 三方库,实现支持鸿蒙 6.0+(API 20+)的原生体验待办 APP,关闭重启数据不丢失。
二、环境准备(必须配置)
-
Flutter SDK:安装支持鸿蒙的正式版(3.13+),确保已切换至适配鸿蒙的分支,避免版本不兼容导致运行失败。
-
DevEco Studio 4.0+:鸿蒙开发专用工具,需安装 API 20+(对应鸿蒙6.0+系统) 的 SDK,否则无法正常适配鸿蒙设备。
-
三方库:
shared_preferences: ^2.2.0,该库已完成鸿蒙端原生适配,无需额外修改代码,可直接用于鸿蒙本地存储。 -
设备:鸿蒙 6.0+ 真机(开启开发者模式、USB调试)或鸿蒙 6.0+ 模拟器,低版本鸿蒙设备无法运行本项目。
三、步骤一:创建 Flutter 鸿蒙项目
打开终端(Windows 用 cmd/PowerShell,macOS/Linux 用终端),执行以下命令,创建仅支持鸿蒙平台的 Flutter 项目:
flutter create --platforms ohos flutter_harmony_todo
说明:--platforms ohos 表示仅创建鸿蒙平台的项目,减少冗余文件,提升开发效率。
创建完成后,进入项目目录:
cd flutter_harmony_todo
四、步骤二:添加三方库依赖
-
打开项目根目录下的
pubspec.yaml文件(该文件是 Flutter 项目的依赖配置文件)。 -
在
dependencies节点下,添加shared_preferences三方库依赖,完整配置如下(保留原有 Flutter 核心依赖):
name: flutter_harmony_todo
description: A new Flutter project for HarmonyOS with third-party library.
version: 1.0.0+1
environment:
sdk: '>=3.1.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
# 核心三方库:鸿蒙适配的本地存储库,用于持久化待办数据
shared_preferences: ^2.2.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
- 保存
pubspec.yaml文件后,在终端执行以下命令,安装三方库:
flutter pub get
注意:执行命令后,若出现 “pub get failed” 错误,大概率是网络问题,关闭代理、切换网络后重新执行即可;若提示版本不兼容,可将 shared_preferences 的版本调整为 ^2.2.0 及以上兼容版本。
五、步骤三:编写待办数据模型
数据模型用于规范待办事项的数据格式,方便后续存储和读取,步骤如下:
-
在
lib文件夹下,新建文件todo_model.dart(右键 lib → New → File)。 -
复制以下代码到
todo_model.dart中,每一行均有详细注释,便于理解:
// 待办事项数据模型类
// 作用:规范待办事项的格式(内容、完成状态),提供序列化/反序列化方法,适配本地存储
class TodoItem {
String content; // 待办任务内容(必填)
bool isCompleted; // 任务是否完成(默认未完成)
// 构造函数:创建待办对象时,必须传入任务内容,完成状态可选(默认false)
TodoItem({
required this.content, // required 表示该参数必须传入
this.isCompleted = false, // 可选参数,默认值为false(未完成)
});
// 序列化方法:将 TodoItem 对象转为 Map 类型
// 原因:shared_preferences 只能存储基本数据类型(字符串、数字等),无法直接存储对象
Map<String, dynamic> toMap() {
return {
'content': content, // 存储任务内容
'isCompleted': isCompleted, // 存储完成状态
};
}
// 反序列化方法:从 Map 类型转回 TodoItem 对象
// 作用:读取本地存储的 Map 数据时,转为我们能直接使用的 TodoItem 对象
factory TodoItem.fromMap(Map<String, dynamic> map) {
return TodoItem(
content: map['content'] ?? '', // 若读取不到内容,默认空字符串
isCompleted: map['isCompleted'] ?? false, // 若读取不到状态,默认未完成
);
}
}
六、步骤四:主页面 + 核心逻辑(完整代码)
主页面是应用的核心,包含 UI 界面、用户交互、三方库调用(数据存储/读取),步骤如下:
-
打开
lib文件夹下的main.dart文件(Flutter 项目的入口文件)。 -
删除原有默认代码,复制以下完整代码,注释详细,新手可逐行阅读理解:
// 导入所需依赖包
import 'package:flutter/material.dart'; // Flutter 核心UI组件库
import 'package:shared_preferences/shared_preferences.dart'; // 三方库:本地存储
import 'dart:convert'; // 用于 JSON 序列化/反序列化
import 'todo_model.dart'; // 导入我们编写的数据模型
// 程序入口:Flutter 应用启动时首先执行的代码
void main() {
runApp(const MyApp());
}
// 根组件:无状态组件(无需动态更新)
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter 鸿蒙待办清单', // 应用标题(鸿蒙设备桌面显示)
debugShowCheckedModeBanner: false, // 关闭调试标签(发布时必须关闭)
theme: ThemeData(primarySwatch: Colors.blue), // 应用主题色(蓝色)
home: const TodoPage(), // 应用首页(待办清单页面)
);
}
}
// 待办清单主页面:有状态组件(需要动态更新 UI,如添加待办、切换完成状态)
class TodoPage extends StatefulWidget {
const TodoPage({super.key});
// 创建状态对象(有状态组件必须重写该方法)
@override
State<TodoPage> createState() => _TodoPageState();
}
// 主页面状态类:处理页面的动态数据和交互逻辑
class _TodoPageState extends State<TodoPage> {
// 待办列表:存储所有待办事项(泛型为我们定义的 TodoItem 类型)
final List<TodoItem> _todoList = [];
// 输入框控制器:用于获取输入框中的文本内容
final TextEditingController _controller = TextEditingController();
// 页面初始化方法:页面加载完成后首先执行
@override
void initState() {
super.initState();
_loadData(); // 初始化时,从鸿蒙本地读取已存储的待办数据
}
// ====================== 三方库核心操作(本地存储/读取) ======================
// 从鸿蒙本地加载待办数据(异步方法,需用 async/await)
Future<void> _loadData() async {
// 1. 获取 shared_preferences 实例(连接鸿蒙本地存储)
final prefs = await SharedPreferences.getInstance();
// 2. 读取存储的待办数据(key 为 "todo_list",存储格式为 JSON 字符串)
String? data = prefs.getString('todo_list');
// 3. 若有数据,解析为 TodoItem 列表,更新 UI
if (data != null) {
List<dynamic> jsonList = jsonDecode(data); // JSON 字符串转列表
setState(() {
// 将列表中的每一个 Map 转为 TodoItem 对象,添加到待办列表
_todoList.addAll(jsonList.map((e) => TodoItem.fromMap(e)).toList());
});
}
}
// 保存待办数据到鸿蒙本地(异步方法)
Future<void> _saveData() async {
// 1. 获取 shared_preferences 实例
final prefs = await SharedPreferences.getInstance();
// 2. 将待办列表转为 JSON 字符串(因为本地存储无法直接存储对象列表)
String jsonData = jsonEncode(_todoList.map((e) => e.toMap()).toList());
// 3. 存储数据(key 为 "todo_list",便于后续读取)
await prefs.setString('todo_list', jsonData);
}
// ====================== 用户交互方法 ======================
// 添加待办任务
void _addTask() {
// 1. 校验输入:输入框内容不为空(去除前后空格)
if (_controller.text.trim().isNotEmpty) {
setState(() {
// 2. 向待办列表添加新任务(使用我们定义的 TodoItem 模型)
_todoList.add(TodoItem(content: _controller.text.trim()));
});
// 3. 清空输入框
_controller.clear();
// 4. 保存新的待办列表到本地
_saveData();
}
}
// 切换待办任务的完成状态(传入任务索引,定位具体任务)
void _toggleStatus(int index) {
setState(() {
// 取反完成状态(true ↔ false)
_todoList[index].isCompleted = !_todoList[index].isCompleted;
});
// 切换状态后,保存更新后的列表到本地
_saveData();
}
// ====================== UI 界面构建 ======================
@override
Widget build(BuildContext context) {
// Scaffold:Flutter 标准页面容器,包含导航栏、主体内容
return Scaffold(
// 导航栏(顶部)
appBar: AppBar(
title: const Text("Flutter 鸿蒙待办清单"), // 导航栏标题
centerTitle: true, // 标题居中
),
// 主体内容(垂直布局:输入区 + 列表区)
body: Column(
children: [
// 1. 输入区域:输入待办任务 + 添加按钮
Padding(
padding: const EdgeInsets.all(10), // 内边距(上下左右各10)
child: Row(
children: [
// 输入框:占满剩余空间
Expanded(
child: TextField(
controller: _controller, // 绑定输入框控制器
decoration: const InputDecoration(
hintText: "请输入待办事项", // 提示文本
border: OutlineInputBorder(), // 输入框边框
),
),
),
const SizedBox(width: 10), // 输入框和按钮之间的间距
// 添加按钮
ElevatedButton(
onPressed: _addTask, // 点击触发添加任务方法
child: const Text("添加"), // 按钮文本
),
],
),
),
// 2. 待办列表区:展示所有待办任务,可滚动
Expanded(
child: ListView.builder(
itemCount: _todoList.length, // 列表项数量 = 待办列表长度
// 列表项构建方法:每一个待办任务对应一个 ListTile
itemBuilder: (context, index) {
return ListTile(
// 待办任务内容
title: Text(
_todoList[index].content,
// 若任务完成,添加删除线
style: TextStyle(
decoration: _todoList[index].isCompleted
? TextDecoration.lineThrough
: null,
color: _todoList[index].isCompleted ? Colors.grey : Colors.black,
),
),
// 右侧复选框:控制任务完成状态
trailing: Checkbox(
value: _todoList[index].isCompleted, // 绑定完成状态
// 点击复选框,切换完成状态
onChanged: (value) => _toggleStatus(index),
),
);
},
),
),
],
),
);
}
}
七、步骤五:鸿蒙设备运行(关键步骤)
7.1 配置鸿蒙签名(必须操作)
鸿蒙系统要求所有应用必须签名才能运行,步骤如下:
-
打开 DevEco Studio,点击「File → Open」,选择 Flutter 项目根目录下的
ohos文件夹(该文件夹是 Flutter 自动生成的鸿蒙工程目录)。 -
等待 DevEco Studio 加载鸿蒙工程完成后,点击「File → Project Structure」(或快捷键 Ctrl+Alt+Shift+S)。
-
在弹出的窗口中,选择「Project → Signing Configs」,点击「Auto Signing」(自动签名),系统会自动生成签名文件,无需手动配置。
-
点击「Apply → OK」,完成签名配置。
注意:若自动签名失败,需检查 DevEco Studio 是否登录华为开发者账号,且已安装鸿蒙 SDK(API 20+)。
7.2 连接设备/启动模拟器
-
真机连接:将鸿蒙 6.0+ 真机通过 USB 连接到电脑,开启手机的「开发者模式」和「USB 调试」(设置 → 关于手机 → 连续点击版本号 7 次,开启开发者模式;再进入系统和更新 → 开发者选项 → 开启 USB 调试)。
-
模拟器启动:打开 DevEco Studio,点击顶部工具栏的「AVD Manager」,创建并启动鸿蒙 6.0+ 模拟器(SDK 版本选择 API 20+)。
7.3 运行项目
-
回到终端,确保当前目录是 Flutter 项目根目录(
flutter_harmony_todo)。 -
执行以下命令,将应用运行到鸿蒙设备/模拟器:
flutter run -d ohos
说明:-d ohos 表示指定运行到鸿蒙设备,若电脑连接了多个设备,可执行 flutter devices 查看设备ID,替换 ohos 为具体设备ID。
7.4 运行成功验证
运行成功后,鸿蒙设备/模拟器上会出现「Flutter 鸿蒙待办清单」应用,可进行以下操作验证功能:
-
在输入框中输入待办任务,点击「添加」,任务会显示在列表中。
-
点击任务右侧的复选框,可切换任务完成状态(完成后显示删除线)。
-
关闭应用,重新打开,之前添加的待办任务依然存在(三方库持久化生效)。
八、常见问题排查(新手必看)
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
执行 flutter pub get 失败 |
网络问题、代理干扰、三方库版本不兼容 | 1. 关闭代理、切换手机热点;2. 将 shared_preferences 版本改为 ^2.2.0;3. 执行 flutter pub cache repair 修复缓存 |
| 鸿蒙设备无法识别 | 未开启 USB 调试、设备未连接、ADB 异常 | 1. 重新开启 USB 调试;2. 重新连接 USB 线;3. 重启电脑和手机 |
| 运行时提示「签名失败」 | 未配置鸿蒙签名、签名文件失效 | 重新配置自动签名,确保 DevEco Studio 登录开发者账号 |
| 应用启动后空白 | 代码错误、三方库未正确导入 | 检查 main.dart 代码是否完整,确保 shared_preferences 已成功安装 |
| 数据无法持久化 | 存储 key 错误、序列化/反序列化失败 | 检查 _saveData 和 _loadData 方法,确保存储 key 为 “todo_list”,数据模型的序列化方法正确 |
九、核心知识点总结
-
Flutter 与鸿蒙的关系:Flutter 是跨端框架,一套代码可直接运行在鸿蒙、Android、iOS 等平台,无需为鸿蒙单独编写 ArkTS 代码。
-
三方库的作用:
shared_preferences简化了鸿蒙本地存储的开发,无需手动操作鸿蒙的 Preferences 数据库,直接调用 API 即可实现数据持久化。 -
有状态与无状态组件:无状态组件(如
MyApp)用于静态 UI,有状态组件(如TodoPage)用于动态 UI(需更新数据、刷新界面)。 -
序列化与反序列化:由于本地存储无法直接存储对象,需将
TodoItem对象转为 Map(序列化),读取时再转回TodoItem(反序列化)。
运行截图如下
更多推荐



所有评论(0)