Flutter for OpenHarmony 实战:HarmonyOS ArkTS API 24 文本去重 - 去除重复行
文本去重工具技术解析文档
一、项目背景概述
本项目是一个基于 Flutter 框架开发的文本去重工具应用,专为 OpenHarmony 平台设计。应用的核心功能是对用户输入的多行文本进行去重处理,去除重复的行,保留唯一的行,帮助用户快速清理重复数据。
从产品定位来看,这是一个实用型文本处理工具,面向需要处理大量文本数据的用户群体,如数据处理人员、内容编辑、开发者等。在日常工作中,经常会遇到需要去除重复行的场景,如整理邮件列表、清理数据导出结果、合并多个文档等,本应用提供了一个简单快捷的解决方案。
技术层面,应用采用 Flutter 的 Material Design 3 设计规范,使用深紫色作为主题色。应用界面分为输入区、操作区和输出区三大部分,结构清晰,操作直观。用户只需将文本粘贴到输入框,点击去重按钮即可得到结果。
应用的核心算法利用了 Dart 语言中 Set 数据结构的去重特性,将文本按行分割后转换为 Set 自动去重,再重新组合为文本。这种实现方式简洁高效,充分利用了语言内置的数据结构能力。
二、架构分析
2.1 整体架构图
2.2 去重处理流程图
2.3 架构层次说明
应用采用简洁的两层组件架构:
第一层:应用根层级
负责应用的全局配置,包括主题、标题等。使用 MaterialApp 作为根组件,提供 Material Design 风格的视觉规范。首页使用 Scaffold 提供基础的页面结构,包括应用栏和可滚动的主体内容。
第二层:功能核心层
文本去重核心组件封装了全部的去重功能,包括输入、处理和输出。这是一个自包含的状态型组件,内部管理输入输出的文本控制器和统计数据。组件内部按照功能划分为四个区域:输入区域、操作区域、输出区域和说明区域。
这种集中式的设计适合功能相对单一的工具类应用,所有相关逻辑都在一个组件内,便于理解和维护。
三、入口组件流程
3.1 应用启动流程
应用的入口函数 main 调用 runApp 方法启动应用。根组件是一个无状态组件,返回 MaterialApp 实例,配置了应用标题、深紫色主题和 Material 3 支持。
首页组件是一个状态型组件,但其状态类非常简洁,构建方法只返回一个包含文本去重组件的 Scaffold。应用栏标题为"文本去重工具",采用深紫色背景和白色前景色。
主体内容使用 SingleChildScrollView 包裹,确保在小屏幕设备上内容可以滚动查看,避免溢出问题。内部是一个垂直列布局,只包含一个文本去重核心组件。
3.2 组件职责划分
首页组件:负责页面框架的搭建,提供应用栏和基础布局结构。本身不持有业务状态,只作为容器存在。
文本去重核心组件:负责全部的去重业务逻辑,包括输入管理、去重计算、结果展示等。是一个自包含的功能模块。
这种职责划分使得首页组件非常轻量,核心功能集中在一个组件中,对于简单的工具应用来说是合理的设计选择。
四、核心组件逐段解析
4.1 文本去重核心组件
文本去重核心组件是整个应用的主体,是一个状态型组件,封装了所有去重相关的功能。
状态变量:
- 输入文本控制器:管理输入文本框的内容
- 输出文本控制器:管理输出文本框的内容
- 原始行数统计:记录去重前的行数
- 去重后行数统计:记录去重后的行数
两个文本控制器分别管理输入和输出,使得输入和输出的状态独立可控。输出文本框设置为只读,用户不能直接修改去重结果。
核心方法:
去重方法是组件的核心功能方法,执行完整的去重流程:
- 获取输入文本
- 非空验证,为空则显示提示并返回
- 按换行符分割为行列表
- 记录原始行数
- 转换为 Set 实现去重
- 记录去重后的行数
- 重新连接为文本字符串
- 设置输出文本框内容
- 显示去重结果提示
清空方法用于清空所有输入输出和统计数据,重置到初始状态。
复制方法用于将去重结果复制到剪贴板。
生命周期管理:
组件在 dispose 方法中释放两个文本控制器的资源,确保内存安全。这是 Flutter 中使用控制器的标准最佳实践。
4.2 输入区域
输入区域包含输入文本框、行数统计和清空按钮三个部分。
输入文本框:
使用 TextField 组件,最多显示6行,内容超出时可滚动。没有边框,通过外部容器的边框来实现视觉边界。设置了占位提示文字,引导用户正确输入。
行数统计:
显示在输入区域左下角,展示当前输入的行数。文字颜色为灰色,字号较小,作为辅助信息存在。
清空按钮:
使用 ElevatedButton.icon 图标按钮,浅灰色背景,深紫色文字。点击后清空输入和输出的所有内容,重置统计数据。
4.3 操作按钮区域
操作区域居中显示一个大的去重按钮,使用 ElevatedButton.icon,带有过滤列表图标和"去除重复行"文字。深紫色背景,白色文字,圆角矩形,较大的内边距,突出主要操作。
这个按钮是应用的核心操作按钮,视觉上突出醒目,引导用户点击。
4.4 输出区域
输出区域的结构与输入区域对称,包含输出文本框、行数统计和复制按钮。
输出文本框:
与输入框样式相同,但设置为只读模式,用户不能编辑去重结果,只能查看和复制。
行数统计:
显示在输出区域左下角,展示去重后的行数。文字颜色为绿色,与输入区域的灰色形成对比,直观地表示这是处理后的结果。
复制按钮:
使用图标按钮,带有复制图标和"复制"文字。点击后将结果复制到剪贴板。
4.5 说明区域
说明区域位于组件底部,使用浅紫色背景的容器包裹,包含使用说明文字。说明以列表形式列出了4条使用步骤,帮助用户快速了解如何使用这个工具。
五、状态管理
5.1 状态架构
本应用采用组件内状态管理方案,所有状态都集中在文本去重核心组件内部管理。这种方案对于功能单一的工具类应用来说简单直接,不需要引入额外的状态管理库。
状态分类:
输入相关状态:
- 输入文本控制器:管理输入文本内容
- 原始行数统计:记录输入的行数
输出相关状态:
- 输出文本控制器:管理输出文本内容
- 去重后行数统计:记录输出的行数
5.2 状态更新流程
状态更新主要发生在以下几个时机:
用户输入时:输入文本控制器自动管理输入内容的变化,但行数统计不会实时更新,只有在执行去重操作时才会更新行数。
点击去重时:执行完整的去重计算,更新输出文本和两个行数统计。这是最主要的状态更新时机。
点击清空时:清空所有状态,重置到初始状态。输入输出文本被清空,行数统计归零。
点击复制时:不改变业务状态,只显示操作反馈提示。
5.3 用户反馈机制
应用通过 SnackBar 机制向用户提供操作反馈:
- 输入为空时点击去重:显示"请输入要去重的文本"
- 去重完成后:显示"去重完成:从 X 行减少到 Y 行"
- 输出为空时点击复制:显示"没有可复制的内容"
- 复制成功时:显示"已复制到剪贴板"
这种即时反馈机制确保用户随时了解操作的结果和当前状态,提升了应用的可用性。
六、关键代码详解
6.1 去重算法实现
文本去重的核心算法非常简洁,利用了 Set 数据结构的去重特性。主要步骤包括:使用 split 方法按换行符将文本分割为字符串列表;调用 toSet 方法将列表转换为 Set,自动去除重复项;调用 toList 方法将 Set 转换回列表;使用 join 方法用换行符将列表重新连接为一个字符串。
这种实现方式充分利用了 Dart 语言内置的集合操作,代码简洁高效。时间复杂度为 O(n),其中 n 是行数,因为 Set 的插入和查找操作平均都是 O(1) 的。
需要注意的是,Set 去重是精确匹配,只有完全相同的行才会被认为是重复的。如果需要忽略首尾空白、忽略大小写等更灵活的去重方式,需要在去重前对每一行进行预处理。
6.2 输入验证机制
应用在执行去重前会进行输入验证,确保输入不为空。这种前置验证避免了无意义的计算,同时给用户明确的提示。验证失败时通过 ScaffoldMessenger 显示 SnackBar 提示,持续2秒后自动消失。
同样,复制功能也会验证输出是否为空,避免在没有结果的情况下执行复制操作。这种防御性编程的思想很重要,它确保了应用在各种边界情况下都能正确运行。
6.3 双控制器模式
应用使用两个独立的文本控制器分别管理输入和输出:
- 输入控制器:管理用户输入的文本,可编辑
- 输出控制器:管理去重后的结果,只读
这种双控制器模式的优势在于:输入和输出的状态完全独立,互不干扰;输出控制器配合 readOnly 属性实现只读效果;便于后续扩展功能。
两个控制器在 dispose 方法中被正确释放,确保资源被回收。这是 Flutter 开发中必须注意的细节,忘记释放控制器是常见的内存泄漏原因之一。
6.4 卡片式布局设计
整个去重组件采用卡片式视觉设计:白色背景、圆角边框、轻微的阴影效果。这种设计营造出悬浮感和层次感,使功能区域与背景清晰分离。
卡片式设计的优点在于:视觉上清晰分区,每个卡片是一个独立的功能单元;阴影和圆角营造质感,提升应用的品质感;响应式布局友好;符合 Material Design 的设计语言。
七、技术总结
7.1 技术亮点
简洁高效的去重算法:利用 Dart 内置的 Set 数据结构实现去重,代码简洁,性能高效。充分利用了语言的内置能力,避免了手动实现去重逻辑的复杂性。
清晰的界面布局:界面分为输入、操作、输出和说明四个区域,结构清晰,操作流程符合用户直觉。输入区和输出区采用对称设计,视觉上平衡美观。
完善的用户反馈:通过 SnackBar 机制提供即时的操作反馈,用户可以清楚地知道每次操作的结果。空输入、成功去重、空复制、复制成功等各种情况都有对应的提示。
良好的用户体验细节:只读的输出框避免用户误操作、绿色的输出行数与灰色的输入行数形成视觉区分、使用说明帮助新用户快速上手。
7.2 可优化点
实时去重:当前需要点击按钮才执行去重,可以增加实时去重选项,用户输入时自动显示去重结果。
高级去重选项:忽略大小写去重、忽略首尾空白去重、去除空白行、自定义分隔符、支持正则表达式匹配去重等。
剪贴板集成:当前复制功能是模拟的,可以接入 Flutter 的剪贴板 API 实现真正的复制功能。
结果导出:支持将去重结果保存为文件或分享到其他应用。
性能优化:对于超大量的文本,可以考虑使用异步处理和进度提示,避免界面卡顿。
7.3 技术价值
本项目展示了如何使用 Flutter 开发一个完整的文本处理工具,涉及文本输入与展示、集合操作、用户交互反馈、布局设计等多个方面。对于学习 Flutter 的开发者来说,这是一个很好的实战练习项目。
特别是利用 Set 进行去重的实现方式,展示了合理选择数据结构的重要性。选择合适的数据结构可以大大简化代码,提高效率。这也是编程中的一项重要思维方式:不是所有功能都需要自己从头实现,很多时候语言和标准库已经提供了高效的解决方案。
项目针对 OpenHarmony 平台的适配也展示了 Flutter 跨平台开发的能力,一套代码可以在不同平台上运行,为开发者提供了极大的便利。

Flutter for OpenHarmony 实战:文本去重 - 去除重复行
目录
前言:跨生态开发的新机遇
在移动开发领域,我们总是面临着选择与适配。今天,你的Flutter应用在Android和iOS上跑得正欢,明天可能就需要考虑一个新的平台:HarmonyOS(鸿蒙)。这不是一道选答题,而是很多团队正在面对的现实。
Flutter的优势很明确——写一套代码,就能在两个主要平台上运行,开发体验流畅。而鸿蒙代表的是下一个时代的互联生态,它不仅仅是手机系统,更着眼于未来全场景的体验。将现有的Flutter应用适配到鸿蒙,听起来像是一个“跨界”任务,但它本质上是一次有价值的技术拓展:让产品触达更多用户,也让技术栈覆盖更广。
不过,这条路走起来并不像听起来那么简单。Flutter和鸿蒙,从底层的架构到上层的工具链,都有着各自的设计逻辑。会遇到一些具体的问题:代码如何组织?原有的功能在鸿蒙上如何实现?那些平台特有的能力该怎么调用?更实际的是,从编译打包到上架部署,整个流程都需要重新摸索。
这篇文章想做的,就是把这些我们趟过的路、踩过的坑,清晰地摊开给你看。我们不会只停留在“怎么做”,还会聊到“为什么得这么做”,以及“如果出了问题该往哪想”。这更像是一份实战笔记,源自真实的项目经验,聚焦于那些真正卡住过我们的环节。
无论你是在为一个成熟产品寻找新的落地平台,还是从一开始就希望构建能面向多端的应用,这里的思路和解决方案都能提供直接的参考。理解了两套体系之间的异同,掌握了关键的衔接技术,不仅能完成这次迁移,更能积累起应对未来技术变化的能力。
混合工程结构深度解析
项目目录架构
当Flutter项目集成鸿蒙支持后,典型的项目结构会发生显著变化。以下是经过ohos_flutter插件初始化后的项目结构:
my_flutter_harmony_app/
├── lib/ # Flutter业务代码(基本不变)
│ ├── main.dart # 应用入口
│ ├── home_page.dart # 首页
│ └── utils/
│ └── platform_utils.dart # 平台工具类
├── pubspec.yaml # Flutter依赖配置
├── ohos/ # 鸿蒙原生层(核心适配区)
│ ├── entry/ # 主模块
│ │ └── src/main/
│ │ ├── ets/ # ArkTS代码
│ │ │ ├── MainAbility/
│ │ │ │ ├── MainAbility.ts # 主Ability
│ │ │ │ └── MainAbilityContext.ts
│ │ │ └── pages/
│ │ │ ├── Index.ets # 主页面
│ │ │ └── Splash.ets # 启动页
│ │ ├── resources/ # 鸿蒙资源文件
│ │ │ ├── base/
│ │ │ │ ├── element/ # 字符串等
│ │ │ │ ├── media/ # 图片资源
│ │ │ │ └── profile/ # 配置文件
│ │ │ └── en_US/ # 英文资源
│ │ └── config.json # 应用核心配置
│ ├── ohos_test/ # 测试模块
│ ├── build-profile.json5 # 构建配置
│ └── oh-package.json5 # 鸿蒙依赖管理
└── README.md
展示效果图片
flutter 实时预览 效果展示
运行到鸿蒙虚拟设备中效果展示
功能代码实现
项目结构调整
在本次开发中,我们首先对项目结构进行了调整,创建了专门的组件目录来存放文本去重功能的实现:
lib/
├── main.dart # 应用入口
└── components/
└── text_duplicate_remover.dart # 文本去重组件
TextDuplicateRemover 组件开发
组件结构设计
TextDuplicateRemover 是本次开发的核心组件,负责实现文本输入、去重处理和结果展示的完整流程。该组件采用了 StatefulWidget 来管理状态,确保用户交互能够实时反映到界面上。
核心功能实现
以下是 TextDuplicateRemover 组件的核心代码实现:
import 'package:flutter/material.dart';
class TextDuplicateRemover extends StatefulWidget {
const TextDuplicateRemover({Key? key}) : super(key: key);
_TextDuplicateRemoverState createState() => _TextDuplicateRemoverState();
}
class _TextDuplicateRemoverState extends State<TextDuplicateRemover> {
final TextEditingController _inputController = TextEditingController();
final TextEditingController _outputController = TextEditingController();
int _originalLineCount = 0;
int _uniqueLineCount = 0;
void _removeDuplicates() {
final inputText = _inputController.text;
if (inputText.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('请输入要去重的文本'),
duration: Duration(seconds: 2),
),
);
return;
}
// 分割文本为行
final lines = inputText.split('\n');
_originalLineCount = lines.length;
// 使用 Set 去重
final uniqueLines = lines.toSet().toList();
_uniqueLineCount = uniqueLines.length;
// 重新组合为文本
final outputText = uniqueLines.join('\n');
_outputController.text = outputText;
// 显示去重结果提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('去重完成:从 $_originalLineCount 行减少到 $_uniqueLineCount 行'),
duration: Duration(seconds: 2),
),
);
}
void _clearInput() {
_inputController.clear();
_outputController.clear();
_originalLineCount = 0;
_uniqueLineCount = 0;
}
void _copyToClipboard() {
if (_outputController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('没有可复制的内容'),
duration: Duration(seconds: 2),
),
);
return;
}
// 这里简化处理,实际应用中应该使用 Clipboard 类
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('已复制到剪贴板'),
duration: Duration(seconds: 2),
),
);
}
void dispose() {
_inputController.dispose();
_outputController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 3,
offset: const Offset(0, 1),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'文本去重',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
const SizedBox(height: 16),
// 输入区域
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'输入文本',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.withOpacity(0.3)),
borderRadius: BorderRadius.circular(6),
),
child: TextField(
controller: _inputController,
maxLines: 6,
decoration: const InputDecoration(
hintText: '请输入多行文本,每行一条...',
border: InputBorder.none,
contentPadding: EdgeInsets.all(12),
),
style: const TextStyle(fontSize: 14),
),
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'行数: $_originalLineCount',
style: const TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
ElevatedButton.icon(
onPressed: _clearInput,
icon: const Icon(Icons.clear, size: 16),
label: const Text('清空'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[100],
foregroundColor: Colors.deepPurple,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
),
),
],
),
],
),
const SizedBox(height: 20),
// 操作按钮
Center(
child: ElevatedButton.icon(
onPressed: _removeDuplicates,
icon: const Icon(Icons.filter_list),
label: const Text('去除重复行'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
),
),
),
const SizedBox(height: 20),
// 输出区域
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'去重结果',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.withOpacity(0.3)),
borderRadius: BorderRadius.circular(6),
),
child: TextField(
controller: _outputController,
maxLines: 6,
readOnly: true,
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(12),
),
style: const TextStyle(fontSize: 14),
),
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'行数: $_uniqueLineCount',
style: const TextStyle(
color: Colors.green,
fontSize: 12,
),
),
ElevatedButton.icon(
onPressed: _copyToClipboard,
icon: const Icon(Icons.copy, size: 16),
label: const Text('复制'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[100],
foregroundColor: Colors.deepPurple,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
),
),
],
),
],
),
const SizedBox(height: 16),
// 说明文本
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.deepPurple[50],
borderRadius: BorderRadius.circular(6),
),
child: const Text(
'说明:\n1. 输入多行文本,每行一条\n2. 点击"去除重复行"按钮进行去重\n3. 去重结果会显示在下方\n4. 可以复制去重后的结果',
style: TextStyle(
color: Colors.deepPurple,
fontSize: 12,
height: 1.5,
),
),
),
],
),
);
}
}
应用入口集成
在 main.dart 文件中,我们集成了 TextDuplicateRemover 组件,构建了完整的应用界面:
import 'package:flutter/material.dart';
import 'components/text_duplicate_remover.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter for openHarmony',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
debugShowCheckedModeBanner: false,
home: const MyHomePage(title: 'Flutter for openHarmony'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('文本去重工具'),
backgroundColor: Colors.deepPurple,
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
TextDuplicateRemover(),
],
),
),
);
}
}
核心功能说明
-
文本输入与管理
- 使用
TextEditingController管理输入和输出文本 - 支持多行文本输入,每行作为一个独立的条目
- 实时显示输入文本的行数
- 使用
-
去重算法实现
- 使用
Set数据结构进行高效去重 - 时间复杂度接近 O(n),适用于处理较大规模的文本
- 保留原始文本的顺序(通过先转为 Set 去重,再转回 List)
- 使用
-
用户交互反馈
- 提供清空输入、去除重复行、复制结果等操作
- 使用
SnackBar显示操作结果和提示信息 - 实时更新去重前后的行数统计
-
界面设计与布局
- 采用卡片式设计,提供清晰的视觉层次
- 响应式布局,适配不同屏幕尺寸
- 合理的间距和边框,提升用户体验
使用方法
-
启动应用
- 运行应用后,会直接进入文本去重工具的主界面
-
输入文本
- 在"输入文本"区域输入要去重的多行文本,每行一条
- 可以看到实时更新的行数统计
-
执行去重
- 点击"去除重复行"按钮,系统会自动处理文本
- 处理完成后会显示去重结果和统计信息
-
查看结果
- 去重后的文本会显示在"去重结果"区域
- 可以看到去重后的行数统计
-
复制结果
- 点击"复制"按钮,可以将去重后的文本复制到剪贴板
-
清空输入
- 点击"清空"按钮,可以清空所有输入和输出内容
本次开发中容易遇到的问题
1. TextStyle 参数错误
问题描述:在开发过程中,使用了 lineHeight 参数设置文本行高,但编译时出现错误。
错误信息:
lib/components/text_duplicate_remover.dart:264:17: Error: No named parameter with the name 'lineHeight'.
lineHeight: 1.5,
^^^^^^^^^^
../flutter_flutter/packages/flutter/lib/src/painting/text_style.dart:482:9: Context: Found this candidate, but the arguments don't match.
const TextStyle({
解决方案:将 lineHeight 参数改为 height 参数,这是 Flutter 中正确的行高设置参数。
修改前:
style: TextStyle(
color: Colors.deepPurple,
fontSize: 12,
lineHeight: 1.5,
),
修改后:
style: TextStyle(
color: Colors.deepPurple,
fontSize: 12,
height: 1.5,
),
2. 状态管理问题
问题描述:在处理文本去重时,需要实时更新界面状态,但如果状态管理不当,可能导致界面不更新。
解决方案:
- 使用
StatefulWidget管理组件状态 - 调用
setState()方法更新状态,触发界面重建 - 确保所有状态变量都在
setState()中更新
3. 用户输入验证
问题描述:用户可能会在未输入文本的情况下点击去重按钮,导致操作无效。
解决方案:
- 在执行去重操作前,检查输入文本是否为空
- 为空时显示提示信息,避免无效操作
- 提供清晰的用户反馈,引导用户正确操作
4. 内存管理
问题描述:TextEditingController 如果不及时释放,可能导致内存泄漏。
解决方案:
- 在
dispose()方法中调用controller.dispose()释放资源 - 确保所有控制器都被正确管理
5. 平台适配问题
问题描述:在不同平台上,文本处理和剪贴板操作可能有差异。
解决方案:
- 使用 Flutter 提供的跨平台 API
- 针对不同平台的特性进行适当的适配
- 测试在不同平台上的运行效果
总结本次开发中用到的技术点
1. Flutter 基础组件
- StatefulWidget:用于管理需要动态更新的界面状态
- TextField:用于文本输入和显示
- ElevatedButton:用于用户操作按钮
- Container:用于布局和样式设置
- Row/Column:用于线性布局
- SnackBar:用于显示临时消息和反馈
2. 状态管理
- setState():用于更新组件状态,触发界面重建
- TextEditingController:用于管理文本输入和输出
- 生命周期管理:使用
initState()和dispose()方法管理资源
3. 文本处理算法
- Set 去重:利用 Set 数据结构的特性进行高效去重
- 字符串操作:使用
split()和join()方法处理文本行 - 列表操作:使用
toSet()和toList()方法转换数据结构
4. 用户界面设计
- 卡片式设计:使用
BoxDecoration创建卡片效果 - 响应式布局:使用
SingleChildScrollView适配不同屏幕 - 视觉层次:通过颜色、间距、边框等元素创建清晰的视觉层次
- 用户反馈:提供即时、清晰的操作反馈
5. 错误处理与调试
- 参数错误处理:正确使用 Flutter API,避免参数错误
- 用户输入验证:对用户输入进行合理的验证和提示
- 资源管理:正确管理控制器等资源,避免内存泄漏
- 编译错误修复:及时修复编译错误,确保代码质量
6. 鸿蒙平台适配
- 项目结构调整:按照鸿蒙项目要求组织代码结构
- 跨平台兼容性:确保代码在鸿蒙平台上正常运行
- 性能优化:考虑鸿蒙平台的性能特性,进行适当优化
7. 开发最佳实践
- 组件化开发:将功能封装为独立组件,提高代码复用性
- 代码可读性:使用清晰的命名和注释,提高代码可读性
- 用户体验:注重界面设计和交互体验,提供直观的操作方式
- 错误处理:完善的错误处理机制,提升应用稳定性
通过本次开发,我们不仅实现了一个实用的文本去重工具,还积累了在 Flutter for OpenHarmony 平台上开发应用的经验。这些技术点和最佳实践,对于后续开发类似应用或进行更复杂的项目,都具有参考价值。

flutter_openHarmony(简称 Flutter‑OH)
注意:不是Google官方产物,是OpenHarmony社区TPC组织维护的Flutter引擎移植版本。把Flutter的Dart/Skia引擎做底层改造,让Flutter应用可以直接编译输出 HAP包,跑在OpenHarmony/纯血鸿蒙设备上,不需要依赖Android兼容层。
简单讲:一套Dart/Flutter业务代码,可以同时编译 Android、iOS、OpenHarmony(HAP)。
核心原理
对Flutter Engine做Embedder嵌入适配,对接OpenHarmony Rosen图形管线、UIAbility生命周期,通过MethodChannel实现 Dart ↔ ArkTS双向通信,Flutter自绘UI渲染到鸿蒙Surface,复用方舟编译器、系统权限、分布式能力。
- Dart业务代码几乎不变
- 底层引擎适配鸿蒙图形、线程、生命周期
- 输出产物是标准HAP应用包,可上架鸿蒙应用市场
主要优势
-
存量Flutter项目低成本接入鸿蒙生态
纯Dart业务、纯Widget界面几乎不用改代码即可编译出鸿蒙HAP;只有带Android/iOS原生桥接的插件,才需要做鸿蒙适配替换。已经有成熟Flutter App,想快速覆盖鸿蒙设备,不用全部重写ArkTS。 -
多端UI高度一致性
Flutter自绘渲染,不受各平台控件差异影响,手机、平板、车机界面表现统一;滚动、动画、首页各类动效(轮播、吸顶、骨架屏、入场动画)跨平台表现一致,和你前面问的App首页各种效果可以一套代码全部实现。 -
继承Flutter完整开发体验
保留热重载、DevTools调试、完整Widget组件库;pub.dev海量纯Dart三方库直接复用,是鸿蒙跨端方案里三方库最丰富的方案。提供定制CLI,一条命令完成编译、真机调试、打包HAP。 -
可调用OpenHarmony原生系统能力
支持调用分布式软总线、分布式数据KV、原子化服务、鸿蒙权限体系、硬件能力;Flutter页面和ArkTS原生页面可以混合开发、互相跳转,复杂原生逻辑继续写ArkTS,UI业务交给Flutter实现。 -
全场景设备覆盖
支持OpenHarmony手机、平板、智慧屏、车机等设备,适合需要多终端统一UI的业务。引擎做了懒加载,跟随UIAbility生命周期启停,控制内存占用,减少后台资源消耗。
更多推荐


所有评论(0)