Flutter 框架跨平台鸿蒙开发 - 剪贴板管理应用
运行效果图剪贴板管理是一款专注于剪贴板历史记录管理的移动应用,为用户提供高效、便捷的剪贴板内容管理体验。在日常工作和生活中,我们经常需要复制粘贴各种内容,但系统剪贴板只能保存最近一次的内容,这给用户带来了诸多不便。本应用帮助用户保存剪贴板历史记录,支持多种内容类型识别,让复制粘贴更加高效。应用支持自动识别内容类型,包括文本、链接、邮箱、电话、代码等六大类型,并为每种类型提供专属图标和颜色标识。搜索
剪贴板管理应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
剪贴板管理是一款专注于剪贴板历史记录管理的移动应用,为用户提供高效、便捷的剪贴板内容管理体验。在日常工作和生活中,我们经常需要复制粘贴各种内容,但系统剪贴板只能保存最近一次的内容,这给用户带来了诸多不便。本应用帮助用户保存剪贴板历史记录,支持多种内容类型识别,让复制粘贴更加高效。
应用支持自动识别内容类型,包括文本、链接、邮箱、电话、代码等六大类型,并为每种类型提供专属图标和颜色标识。收藏功能让用户可以标记重要内容,便于快速查找。搜索功能支持按内容、标题、标签进行模糊搜索,快速定位目标记录。统计功能展示使用数据,让用户了解自己的剪贴板使用习惯。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 剪贴板列表 | 历史记录浏览与管理 | ListView + Card |
| 内容分类 | 按类型筛选记录 | FilterChip |
| 搜索功能 | 模糊搜索记录内容 | TextField + 过滤 |
| 收藏管理 | 标记重要内容收藏 | 状态管理 |
| 统计分析 | 使用数据可视化 | 图表展示 |
| 设置管理 | 应用配置与偏好 | ListView |
1.3 剪贴板属性
| 属性 | 类型 | 说明 |
|---|---|---|
| 记录ID | String | 唯一标识 |
| 内容 | String | 剪贴板内容 |
| 类型 | ClipType | 内容类型 |
| 标题 | String? | 自定义标题 |
| 预览 | String? | 内容预览 |
| 是否收藏 | bool | 收藏状态 |
| 创建时间 | DateTime | 创建时间 |
| 复制时间 | DateTime? | 最近复制时间 |
| 复制次数 | int | 累计复制次数 |
| 标签 | List | 自定义标签 |
1.4 内容类型
| 类型 | 图标 | 颜色 | 识别规则 |
|---|---|---|---|
| 文本 | text_fields | 蓝色 | 默认类型 |
| 链接 | link | 绿色 | https?😕/开头 |
| 邮箱 | 橙色 | 邮箱格式 | |
| 电话 | phone | 紫色 | 电话号码格式 |
| 图片 | image | 粉色 | 图片数据 |
| 代码 | code | 青色 | 包含代码特征 |
1.5 分类筛选
| 分类 | 图标 | 说明 |
|---|---|---|
| 全部 | select_all | 显示所有记录 |
| 收藏 | star | 仅显示收藏记录 |
| 文本 | text_fields | 仅显示文本类型 |
| 链接 | link | 仅显示链接类型 |
| 代码 | code | 仅显示代码类型 |
1.6 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 日期处理 | intl | ^0.19.0 |
| 剪贴板API | Clipboard | Flutter SDK |
| 目标平台 | 鸿蒙OS | API 21+ |
1.7 项目结构
lib/
└── main_clipboard.dart
├── ClipboardManagerApp # 应用入口
├── ClipType # 内容类型枚举
├── ClipCategory # 分类枚举
├── ClipItem # 剪贴板数据模型
└── ClipboardHomePage # 主页面
├── _buildClipboardPage() # 剪贴板列表页
├── _buildCategoryPage() # 分类管理页
├── _buildStatisticsPage() # 统计页面
├── _buildSettingsPage() # 设置页面
├── _buildClipItemCard() # 记录卡片
└── _showItemDetail() # 详情弹窗
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 数据流程图
2.4 内容识别流程
三、核心模块设计
3.1 数据模型设计
3.1.1 内容类型枚举 (ClipType)
enum ClipType {
text('文本', Icons.text_fields, Colors.blue),
link('链接', Icons.link, Colors.green),
email('邮箱', Icons.email, Colors.orange),
phone('电话', Icons.phone, Colors.purple),
image('图片', Icons.image, Colors.pink),
code('代码', Icons.code, Colors.teal);
final String label;
final IconData icon;
final Color color;
const ClipType(this.label, this.icon, this.color);
}
3.1.2 分类枚举 (ClipCategory)
enum ClipCategory {
all('全部', Icons.select_all),
favorite('收藏', Icons.star),
text('文本', Icons.text_fields),
link('链接', Icons.link),
code('代码', Icons.code);
final String label;
final IconData icon;
const ClipCategory(this.label, this.icon);
}
3.1.3 剪贴板模型 (ClipItem)
class ClipItem {
final String id; // 唯一标识
final String content; // 内容
final ClipType type; // 类型
final String? title; // 标题
final String? preview; // 预览
final bool isFavorite; // 是否收藏
final DateTime createdAt; // 创建时间
final DateTime? copiedAt; // 复制时间
final int copyCount; // 复制次数
final List<String> tags; // 标签
ClipItem copyWith({...}) => ClipItem(...);
}
3.2 内容识别逻辑
3.2.1 识别流程
3.2.2 识别实现
ClipType _detectContentType(String content) {
// 链接检测
if (RegExp(r'^https?://').hasMatch(content)) {
return ClipType.link;
}
// 邮箱检测
if (RegExp(r'^[\w.-]+@[\w.-]+\.\w+$').hasMatch(content)) {
return ClipType.email;
}
// 电话检测
if (RegExp(r'^\d{3,4}-?\d{7,8}$|^\d{11}$').hasMatch(content)) {
return ClipType.phone;
}
// 代码检测
if (content.contains('{') || content.contains('function')) {
return ClipType.code;
}
return ClipType.text;
}
3.3 搜索过滤逻辑
3.3.1 过滤流程
3.3.2 过滤实现
List<ClipItem> get _filteredItems {
var items = _clipItems.toList();
// 分类筛选
if (_selectedCategory == ClipCategory.favorite) {
items = items.where((item) => item.isFavorite).toList();
} else if (_selectedCategory != ClipCategory.all) {
// 按类型筛选
}
// 搜索筛选
if (_searchQuery.isNotEmpty) {
items = items.where((item) {
return item.content.toLowerCase().contains(_searchQuery.toLowerCase()) ||
(item.title?.toLowerCase().contains(_searchQuery.toLowerCase()) ?? false) ||
item.tags.any((tag) => tag.toLowerCase().contains(_searchQuery.toLowerCase()));
}).toList();
}
return items..sort((a, b) => b.createdAt.compareTo(a.createdAt));
}
3.4 页面结构设计
3.4.1 主页面布局
3.5 状态管理
3.5.1 核心状态变量
class _ClipboardHomePageState extends State<ClipboardHomePage> {
int _selectedIndex = 0; // 当前Tab索引
final List<ClipItem> _clipItems = []; // 剪贴板记录
ClipCategory _selectedCategory = ClipCategory.all; // 当前分类
final TextEditingController _searchController = TextEditingController();
String _searchQuery = ''; // 搜索关键词
}
四、UI设计规范
4.1 配色方案
应用采用青色主题风格,体现清新与高效:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | Cyan | AppBar、强调、按钮 |
| 文本 | Blue | 文本类型标识 |
| 链接 | Green | 链接类型标识 |
| 邮箱 | Orange | 邮箱类型标识 |
| 电话 | Purple | 电话类型标识 |
| 代码 | Teal | 代码类型标识 |
4.2 内容类型颜色映射
| 类型 | 颜色 | 说明 |
|---|---|---|
| 文本 | 蓝色 | 普通文本内容 |
| 链接 | 绿色 | URL链接 |
| 邮箱 | 橙色 | 电子邮箱 |
| 电话 | 紫色 | 电话号码 |
| 图片 | 粉色 | 图片数据 |
| 代码 | 青色 | 代码片段 |
4.3 组件规范
4.3.1 剪贴板卡片
┌─────────────────────────────────────────────────────────────┐
│ ┌────┐ Flutter简介 ⭐ ⋮ │
│ │ 📝 │ 文本 │
│ └────┘ │
├─────────────────────────────────────────────────────────────┤
│ Flutter是Google推出的跨平台移动应用开发框架... │
├─────────────────────────────────────────────────────────────┤
│ 🕐 03-18 14:30 📋 5次 [技术] [Flutter] │
└─────────────────────────────────────────────────────────────┘
4.3.2 分类卡片
┌─────────────────────────────────────────────────────────────┐
│ ┌────┐ 文本 > │
│ │ 📝 │ 12 条记录 │
│ └────┘ │
└─────────────────────────────────────────────────────────────┘
4.3.3 统计概览
┌─────────────────────────────────────────────────────────────┐
│ 📋 📋 ⭐ │
│ 25 48 8 │
│ 总记录 复制次数 收藏数 │
└─────────────────────────────────────────────────────────────┘
4.3.4 详情弹窗
┌─────────────────────────────────────────────────────────────┐
│ ┌────┐ Flutter入口代码 ✕ │
│ │ 💻 │ │
│ └────┘ │
├─────────────────────────────────────────────────────────────┤
│ void main() { │
│ runApp(const MyApp()); │
│ } │
├─────────────────────────────────────────────────────────────┤
│ 🕐 2024-03-18 14:30 📋 复制15次 ⭐ 已收藏 │
│ [Dart] [Flutter] │
├─────────────────────────────────────────────────────────────┤
│ [复制] [取消收藏] │
│ [删除] │
└─────────────────────────────────────────────────────────────┘
4.4 交互设计
4.4.1 操作方式
| 操作 | 手势 | 效果 |
|---|---|---|
| 查看详情 | 点击卡片 | 弹出详情面板 |
| 复制内容 | 点击复制按钮 | 复制到剪贴板 |
| 收藏/取消 | 点击收藏按钮 | 切换收藏状态 |
| 删除记录 | 点击删除按钮 | 删除该记录 |
| 搜索内容 | 输入搜索词 | 过滤匹配记录 |
| 切换分类 | 点击分类标签 | 筛选类型记录 |
五、核心功能实现
5.1 主页面构建
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _selectedIndex,
children: [
_buildClipboardPage(),
_buildCategoryPage(),
_buildStatisticsPage(),
_buildSettingsPage(),
],
),
bottomNavigationBar: NavigationBar(
selectedIndex: _selectedIndex,
onDestinationSelected: (index) {
setState(() {
_selectedIndex = index;
});
},
destinations: const [
NavigationDestination(icon: Icon(Icons.content_paste_outlined), label: '剪贴板'),
NavigationDestination(icon: Icon(Icons.category_outlined), label: '分类'),
NavigationDestination(icon: Icon(Icons.bar_chart_outlined), label: '统计'),
NavigationDestination(icon: Icon(Icons.settings_outlined), label: '设置'),
],
),
);
}
5.2 剪贴板卡片
Widget _buildClipItemCard(ClipItem item) {
return Card(
child: InkWell(
onTap: () => _showItemDetail(item),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
children: [
Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: item.type.color.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(item.type.icon, size: 18, color: item.type.color),
),
// ...内容信息
PopupMenuButton<String>(
onSelected: (value) {
if (value == 'copy') _copyToClipboard(item);
else if (value == 'favorite') _toggleFavorite(item);
else if (value == 'delete') _deleteItem(item);
},
itemBuilder: (context) => [
const PopupMenuItem(value: 'copy', child: Text('复制')),
PopupMenuItem(value: 'favorite', child: Text(item.isFavorite ? '取消收藏' : '收藏')),
const PopupMenuItem(value: 'delete', child: Text('删除')),
],
),
],
),
// ...预览内容
],
),
),
),
);
}
5.3 粘贴功能
void _pasteFromClipboard() async {
final data = await Clipboard.getData(Clipboard.kTextPlain);
if (data?.text != null && data!.text!.isNotEmpty) {
final content = data.text!;
final type = _detectContentType(content);
setState(() {
_clipItems.insert(
0,
ClipItem(
id: DateTime.now().millisecondsSinceEpoch.toString(),
content: content,
type: type,
),
);
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('已添加到剪贴板')),
);
}
}
5.4 复制功能
void _copyToClipboard(ClipItem item) async {
await Clipboard.setData(ClipboardData(text: item.content));
setState(() {
final index = _clipItems.indexWhere((i) => i.id == item.id);
if (index != -1) {
_clipItems[index] = item.copyWith(
copyCount: item.copyCount + 1,
copiedAt: DateTime.now(),
);
}
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('已复制到剪贴板')),
);
}
5.5 详情弹窗
void _showItemDetail(ClipItem item) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => DraggableScrollableSheet(
initialChildSize: 0.7,
maxChildSize: 0.95,
minChildSize: 0.5,
expand: false,
builder: (context, scrollController) => Container(
padding: const EdgeInsets.all(20),
child: ListView(
controller: scrollController,
children: [
// 内容展示
Container(
child: SelectableText(item.content),
),
// 操作按钮
Row(
children: [
FilledButton.icon(onPressed: () => _copyToClipboard(item), icon: Icon(Icons.copy), label: Text('复制')),
OutlinedButton.icon(onPressed: () => _toggleFavorite(item), icon: Icon(Icons.star), label: Text('收藏')),
],
),
],
),
),
),
);
}
六、剪贴板管理知识拓展
6.1 剪贴板工作原理
6.2 内容类型识别规则
| 类型 | 正则表达式 | 示例 |
|---|---|---|
| 链接 | ^https?:// |
https://example.com |
| 邮箱 | ^[\w.-]+@[\w.-]+\.\w+$ |
user@example.com |
| 电话 | ^\d{3,4}-?\d{7,8}$ |
010-12345678 |
| 手机 | ^\d{11}$ |
13812345678 |
| 代码 | 包含{或function |
function foo() {} |
6.3 剪贴板安全考虑
6.4 剪贴板使用场景
| 场景 | 使用频率 | 常见内容 |
|---|---|---|
| 日常办公 | 高 | 文本、链接 |
| 程序开发 | 高 | 代码片段 |
| 数据录入 | 中 | 表单数据 |
| 内容创作 | 中 | 文案素材 |
| 研究学习 | 低 | 参考资料 |
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 自动监听
| 功能 | 说明 |
|---|---|
| 后台监听 | 自动捕获复制操作 |
| 实时同步 | 即时更新记录列表 |
| 智能过滤 | 排除重复内容 |
7.2.2 云同步
| 功能 | 说明 |
|---|---|
| 账号登录 | 用户身份认证 |
| 数据同步 | 多设备数据同步 |
| 历史恢复 | 恢复删除记录 |
7.2.3 快捷操作
| 功能 | 说明 |
|---|---|
| 快捷键 | 键盘快捷操作 |
| 悬浮窗 | 快速访问入口 |
| 通知栏 | 状态栏快捷方式 |
八、注意事项
8.1 开发注意事项
-
颜色处理:使用
withValues(alpha:)替代已废弃的withOpacity() -
日期格式化:使用intl包的DateFormat进行日期格式化
-
剪贴板API:使用Flutter的Clipboard类进行剪贴板操作
-
异步操作:剪贴板操作是异步的,需要使用async/await
-
BuildContext:异步操作后使用BuildContext需要检查mounted
8.2 用户体验优化
📋 用户体验建议 📋
- 内容预览清晰直观
- 类型识别准确快速
- 操作流程简单便捷
- 搜索功能高效精准
8.3 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 剪贴板读取失败 | 权限未授权 | 检查应用权限 |
| 内容类型识别错误 | 正则表达式不完善 | 优化识别规则 |
| 复制次数不准确 | 状态未同步更新 | 使用copyWith创建新对象 |
| 搜索结果为空 | 大小写匹配问题 | 统一转小写比较 |
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| intl包 | ^0.19.0 |
| 鸿蒙OS | API 21+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_clipboard.dart
# 运行到Windows
flutter run -d windows -t lib/main_clipboard.dart
# 代码分析
flutter analyze lib/main_clipboard.dart
十、总结
剪贴板管理应用通过完善的功能设计,帮助用户高效管理剪贴板历史记录。应用支持自动识别内容类型,包括文本、链接、邮箱、电话、代码等六大类型,为每种类型提供专属图标和颜色标识,让用户快速识别内容类型。
收藏功能让用户可以标记重要内容,便于快速查找和访问。搜索功能支持按内容、标题、标签进行模糊搜索,快速定位目标记录。分类筛选功能支持按类型过滤记录,让管理更加有序。
统计功能展示使用数据,包括总记录数、复制次数、收藏数等,让用户了解自己的剪贴板使用习惯。类型分布图表直观展示各类型占比,复制排行榜展示最常使用的内容。
界面设计采用青色主题风格,体现清新与高效。记录卡片通过类型颜色区分不同内容,预览区域展示内容摘要。应用采用Material Design 3设计规范,遵循Flutter最佳实践,代码结构清晰,易于维护和扩展。
高效管理,一键复制!
更多推荐



所有评论(0)