【maaath】Flutter for OpenHarmony 诗词大会应用的鸿蒙化开发实战
功能模块说明诗词背诵挑战随机抽取诗词,填空式背诵,即时判分飞花令对战双人轮流说出含指定关键字的诗句诗句接龙首尾字相接,AI 辅助提示诗词闯关游戏5 关递进式选择题挑战诗词作者介绍8 位著名诗人的生平与作品每日诗词推荐每日一首精选诗词配赏析诗词水平测试10 道随机题目,5 级评级体系整个项目基于 Flutter 框架开发,使用 Dart 语言编写,通过 Flutter for OpenHarmony
Flutter 诗词大会应用的鸿蒙化开发实战
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
作者:maaath
一、引言
随着国产操作系统生态的蓬勃发展,OpenHarmony 作为一款面向全场景的分布式操作系统,正吸引着越来越多的开发者加入。Flutter 作为 Google 开源的跨平台 UI 框架,凭借其高性能、丰富的组件库和活跃的社区生态,已成为移动端开发的主流选择之一。而 Flutter for OpenHarmony 的出现,让开发者能够将已有的 Flutter 应用快速迁移到鸿蒙设备上,实现一次编写、多端运行。
本文将带领读者从零开始,使用 Flutter 构建一款功能完整的"诗词大会"应用,并成功运行在 OpenHarmony 设备上。通过本文的实践,读者将掌握 Flutter 在鸿蒙平台上的开发流程、数据管理、页面路由等核心技能。
二、项目概述
"诗词大会"是一款面向诗词爱好者的综合性学习与娱乐应用,包含以下 8 大核心功能模块:
| 功能模块 | 说明 |
|---|---|
| 诗词背诵挑战 | 随机抽取诗词,填空式背诵,即时判分 |
| 飞花令对战 | 双人轮流说出含指定关键字的诗句 |
| 诗句接龙 | 首尾字相接,AI 辅助提示 |
| 诗词闯关游戏 | 5 关递进式选择题挑战 |
| 诗词作者介绍 | 8 位著名诗人的生平与作品 |
| 诗词收藏背诵 | 收藏喜爱的诗词,支持默写检测 |
| 每日诗词推荐 | 每日一首精选诗词配赏析 |
| 诗词水平测试 | 10 道随机题目,5 级评级体系 |
整个项目基于 Flutter 框架开发,使用 Dart 语言编写,通过 Flutter for OpenHarmony 的适配层,无需修改任何平台代码即可在鸿蒙设备上运行。
三、项目架构设计
3.1 整体架构
项目采用经典的分层架构,分为数据模型层、服务层和页面展示层:
lib/
├── main.dart # 应用入口
├── models/
│ └── poetry_model.dart # 数据模型定义
├── services/
│ └── poetry_service.dart # 业务逻辑与数据管理
└── pages/
├── home_page.dart # 主页面入口
└── poetry/
├── poetry_home_page.dart # 诗词大会首页
├── recite_challenge_page.dart # 背诵挑战
├── feihualing_page.dart # 飞花令对战
├── poetry_chain_page.dart # 诗句接龙
├── challenge_game_page.dart # 闯关游戏
├── author_intro_page.dart # 作者介绍
├── collection_page.dart # 收藏背诵
├── daily_recommend_page.dart # 每日推荐
└── level_test_page.dart # 水平测试
3.2 数据模型设计
数据模型是整个应用的基石。我们使用 Dart 的类来定义诗词、作者、游戏状态等核心数据结构。以下是 Poetry 模型的定义:
class Poetry {
final String id;
final String title;
final String author;
final String dynasty;
final String content;
final List<String> lines;
final String category;
final String description;
bool isFavorite;
Poetry({
required this.id,
required this.title,
required this.author,
required this.dynasty,
required this.content,
required this.lines,
required this.category,
required this.description,
this.isFavorite = false,
});
String get firstChar => lines.isNotEmpty ? lines.first[0] : '';
String get lastChar => lines.isNotEmpty ? lines.last[lines.last.length - 1] : '';
}
这里的关键设计点是 lines 字段将诗词按行拆分,便于后续的填空背诵、接龙等功能的实现。firstChar 和 lastChar 两个 getter 方法用于诗句接龙功能中获取首尾字。
3.3 服务层设计
服务层采用单例模式,集中管理所有诗词数据和游戏逻辑。核心代码如下:
class PoetryService {
static final PoetryService _instance = PoetryService._();
factory PoetryService() => _instance;
PoetryService._();
final List<Poetry> _poems = [];
final List<PoetryAuthor> _authors = [];
final List<ChallengeLevel> _levels = [];
final Random _random = Random();
// 获取每日推荐诗词
Poetry getDailyPoem() {
_initData();
final today = DateTime.now();
final dateKey = DateTime(today.year, today.month, today.day);
if (_dailyPoem != null && _dailyPoemDate == dateKey) {
return _dailyPoem!;
}
_dailyPoemDate = dateKey;
_dailyPoem = _poems[_random.nextInt(_poems.length)];
return _dailyPoem!;
}
// 生成背诵挑战
ReciteChallenge generateReciteChallenge() {
_initData();
final poem = _poems[_random.nextInt(_poems.length)];
final lineCount = poem.lines.length;
final blankCount = min(3, lineCount);
final blankPositions = <int>[];
final correctAnswers = <String>[];
final indices = List.generate(lineCount, (i) => i)..shuffle(_random);
for (var i = 0; i < blankCount; i++) {
blankPositions.add(indices[i]);
correctAnswers.add(poem.lines[indices[i]]);
}
blankPositions.sort();
return ReciteChallenge(
poetry: poem,
blankPositions: blankPositions,
correctAnswers: correctAnswers,
);
}
// 搜索诗词
List<Poetry> searchPoems(String query) {
_initData();
if (query.isEmpty) return allPoems;
return _poems.where((p) =>
p.title.contains(query) ||
p.author.contains(query) ||
p.content.contains(query) ||
p.lines.any((line) => line.contains(query))
).toList();
}
}
服务层封装了数据初始化、随机抽取、搜索过滤等核心逻辑,页面层只需调用相应方法即可获取数据,实现了关注点分离。
四、核心功能实现
4.1 诗词背诵挑战
背诵挑战功能随机选取一首诗词,将其中的若干行挖空,用户需要在空白处填入正确的诗句。实现思路如下:
Widget _buildBlankLine(int index) {
final blankIndex = _challenge.blankPositions.indexOf(index);
final correctAnswer = _challenge.correctAnswers[blankIndex];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: _submitted
? _buildSubmittedBlank(index, blankIndex, correctAnswer)
: TextFormField(
controller: _controllers[index],
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 18,
color: Color(0xFF8B4513),
fontFamily: 'serif',
),
decoration: InputDecoration(
hintText: '请输入第${blankIndex + 1}句',
filled: true,
fillColor: Color(0xFFFFF8DC),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Color(0xFFDEB887)),
),
),
validator: (value) {
if (value == null || value.trim().isEmpty) {
return '请填写诗句';
}
return null;
},
),
);
}
提交后系统会逐句比对,显示对错并给出正确答案,同时累计得分。这种即时反馈机制能有效提升学习效果。
4.2 飞花令对战
飞花令是传统诗词游戏,两人轮流说出含有指定关键字的诗句。我们实现了双人对战模式,并提供了 AI 代答功能:
void _submitAnswer() {
final answer = _answerController.text.trim();
if (answer.isEmpty) {
setState(() => _message = '请输入诗句');
return;
}
if (!_poetryService.validateFeihualingAnswer(_game!, answer)) {
setState(() => _message = '未找到含有"${_game!.keyword}"的诗句,或已被使用');
return;
}
setState(() {
if (_game!.currentPlayer == 1) {
_game!.player1Answers = [..._game!.player1Answers, answer];
_game!.player1Score++;
_game!.currentPlayer = 2;
_message = '玩家1得分!轮到玩家2';
} else {
_game!.player2Answers = [..._game!.player2Answers, answer];
_game!.player2Score++;
_game!.currentPlayer = 1;
_message = '玩家2得分!轮到玩家1';
}
_answerController.clear();
});
}
AI 代答功能会从诗词库中检索未被使用过的、包含关键字的诗句,让单人也能畅玩飞花令。
4.3 诗词闯关游戏
闯关游戏设计了 5 个递进式关卡,每关 5 道选择题,涵盖诗词背诵、作者知识、文学常识等。关卡解锁机制增加了游戏的挑战性:
void _finishLevel() {
final level = _levels[_currentLevelIndex!];
final totalQuestions = level.questions.length;
final score = (_correctCount / totalQuestions * 100).round();
if (score >= level.requiredScore) {
level.isCompleted = true;
level.bestScore = score > level.bestScore ? score : level.bestScore;
if (_currentLevelIndex! + 1 < _levels.length) {
_levels[_currentLevelIndex! + 1].isUnlocked = true;
}
}
// 弹出结果对话框
}
4.4 每日诗词推荐
每日推荐功能根据当前日期缓存一首诗词,确保用户每天打开应用都能看到不同的推荐内容:
Poetry getDailyPoem() {
_initData();
final today = DateTime.now();
final dateKey = DateTime(today.year, today.month, today.day);
if (_dailyPoem != null && _dailyPoemDate == dateKey) {
return _dailyPoem!;
}
_dailyPoemDate = dateKey;
_dailyPoem = _poems[_random.nextInt(_poems.length)];
return _dailyPoem!;
}
五、Flutter for OpenHarmony 适配要点
5.1 项目配置
在将 Flutter 项目迁移到 OpenHarmony 时,需要确保 pubspec.yaml 中不包含鸿蒙不支持的第三方依赖。本项目仅使用了 Flutter 官方 SDK 和 cupertino_icons,无需额外适配:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
5.2 构建与运行
在鸿蒙设备上运行 Flutter 应用,需要先配置好 Flutter for OpenHarmony 的开发环境。构建命令与标准 Flutter 项目一致:
# 调试模式构建
flutter build ohos --debug
# 运行到鸿蒙设备
flutter run --device-ohos
5.3 兼容性注意事项
在开发过程中,有几个关键的兼容性要点需要留意:
-
图标使用:部分 Material Icons 在鸿蒙平台上可能不可用,建议使用基础图标集。例如
Icons.swords不可用,应替换为Icons.shield。 -
字符串操作:Dart 的
charactersAPI 在部分 Flutter for OpenHarmony 版本中可能不支持,建议使用下标索引[0]和[length - 1]替代。 -
列表可变性:在模型类中,如果需要在运行时修改列表内容,不要使用
final修饰,应声明为可变列表。
六、运行效果展示
以下是在鸿蒙设备上运行"诗词大会"应用的截图:
6.1 诗词大会首页
首页展示了每日推荐诗词和 8 大功能入口,采用中国传统色调(棕色、米色)营造古典氛围。顶部渐变背景搭配"赏中华诗词,寻文化基因,品生活之美"的标语,突出文化主题。
6.2 背诵挑战界面
背诵挑战页面随机选取诗词,将部分诗句挖空。用户填写后提交,系统会逐句比对并显示对错。答对全部题目可获得满分评价。

6.3 飞花令对战界面
飞花令对战页面支持双人轮流作答,实时显示比分。用户可选择"花、月、风、春"等 15 个关键字,AI 代答功能让单人也能畅玩。

6.4 闯关游戏界面
闯关游戏包含 5 个递进式关卡,每关 5 道选择题。答对一定比例即可解锁下一关,并记录最高分。


6.5 水平测试结果
水平测试完成后,系统根据正确率给出 5 级评级(诗词新秀→诗词大师),并显示详细得分和评语。

注:以上截图均来自鸿蒙真机运行效果,验证了 Flutter for OpenHarmony 的完整兼容性。
七、总结与展望
本文详细介绍了使用 Flutter 构建"诗词大会"应用并在 OpenHarmony 平台上运行的全过程。通过 8 大功能模块的实现,展示了 Flutter 在鸿蒙生态中的强大能力。
Flutter for OpenHarmony 为开发者提供了一条低成本的跨平台开发路径。对于已有 Flutter 经验开发者来说,迁移成本极低;对于新入门的开发者,Flutter 丰富的组件库和完善的工具链也能大幅提升开发效率。
未来,我们可以进一步扩展应用功能,例如接入在线诗词数据库、实现用户对战匹配、添加语音朗诵识别等。随着 OpenHarmony 生态的不断完善,Flutter 在鸿蒙平台上的表现也将越来越出色。
八、获取源码
欢迎访问 AtomGit(https://atomgit.com)获取完整源码,也欢迎加入开源鸿蒙跨平台社区(https://openharmonycrossplatform.csdn.net)交流讨论,共同推动 Flutter for OpenHarmony 生态发展。
更多推荐



所有评论(0)