8.3 KiB
8.3 KiB
高级功能开发总结
概述
基于对 ONLYOFFICE 官方 Android 和 iOS 项目的深入研究,我创建了一个高级功能分支,提供了完整的编辑器控制能力。
官方项目研究成果
从官方 Android 项目学到的关键实现
-
WebView 桥接模式
- 使用
addJavascriptInterface在原生代码和 JavaScript 之间通信 - 实现双向通信:Flutter ↔ JavaScript ↔ DocsAPI
- 使用
-
图片插入流程
用户点击插入图片 → 编辑器触发 onRequestInsertImage 事件 → Flutter 打开图片选择器 → 上传图片到服务器 → 调用 docEditor.insertImage() 方法 -
文件下载处理
- 拦截下载 URL
- 使用原生下载管理器
- 保存到本地存储
从官方 iOS 项目学到的关键实现
-
WKWebView 消息处理
- 使用
WKScriptMessageHandler接收消息 - 实现
evaluateJavaScript调用编辑器方法
- 使用
-
生命周期管理
onAppReady: 编辑器应用加载完成onDocumentReady: 文档加载完成,可以调用方法onDocumentStateChange: 跟踪文档修改状态
-
权限和安全
- 相机/相册权限请求
- 文件访问权限
- JWT 签名验证
实现的高级功能
1. YxOnlyOfficeAdvancedViewer
完整的高级查看器,提供:
class YxOnlyOfficeAdvancedViewer extends StatefulWidget {
// WebViewController 访问
final Function(WebViewController controller)? onControllerReady;
// 生命周期事件
final Function()? onDocumentReady;
final Function()? onAppReady;
// 图片插入
final Future<String?> Function()? onRequestImageFromGallery;
final Future<String?> Function()? onRequestImageFromCamera;
// 文件下载
final Future<void> Function(String url, String filename)? onDownloadFile;
// 其他配置...
}
2. 编辑器方法调用
直接调用 DocsAPI 方法:
// 插入图片
await viewerState.insertImage('https://example.com/image.jpg');
// 下载文档
await viewerState.downloadAs('pdf');
// 设置审阅模式
await viewerState.setReviewerMode(true);
// 显示修订
await viewerState.showReviewChanges(true);
// 销毁编辑器
await viewerState.destroyEditor();
// 执行自定义 JavaScript
await viewerState.executeJavaScript('window.docEditor.getDocumentName()');
3. EditorMethodResult
统一的方法调用结果:
class EditorMethodResult {
final bool success;
final dynamic data;
final String? error;
}
4. 图片插入完整流程
// 1. 用户触发插入
onRequestInsertImage: (data) async {
// 2. 选择图片来源
final source = await showDialog(...);
// 3. 打开图片选择器
final image = await ImagePicker().pickImage(source: source);
// 4. 上传到服务器
final imageUrl = await uploadImage(image);
// 5. 插入到文档
await viewerState.insertImage(imageUrl);
}
5. 文件下载处理
onDownloadFile: (url, filename) async {
// 1. 下载文件
final response = await http.get(Uri.parse(url));
// 2. 保存到本地
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/$filename');
await file.writeAsBytes(response.bodyBytes);
// 3. 通知用户
print('文件已保存: ${file.path}');
}
完整示例应用
创建了 example/lib/main_advanced.dart,展示:
- ✅ 图片插入(相机/相册)
- ✅ 文件下载(多种格式)
- ✅ 审阅模式切换
- ✅ 显示修订
- ✅ 自定义 JavaScript 执行
- ✅ 完整的错误处理
- ✅ 用户友好的 UI
- ✅ 编辑器信息面板
文件结构
lib/src/
├── onlyoffice_config.dart # 配置类(已有)
├── onlyoffice_html_builder.dart # HTML 构建器(已有)
├── onlyoffice_viewer.dart # 基础查看器(已有)
└── onlyoffice_advanced_viewer.dart # 🆕 高级查看器
example/lib/
├── main.dart # 基础示例(已有)
└── main_advanced.dart # 🆕 高级功能示例
docs/
├── API_REFERENCE.md # API 参考(已有)
├── QUICK_START.md # 快速开始(已有)
├── REFACTORING_SUMMARY.md # 重构总结(已有)
└── ADVANCED_FEATURES.md # 🆕 高级功能指南
与官方实现的对比
| 功能 | 官方 Android/iOS | 我们的实现 | 状态 |
|---|---|---|---|
| 文档查看/编辑 | ✅ | ✅ | ✅ 完成 |
| WebView 桥接 | ✅ | ✅ | ✅ 完成 |
| 图片插入 | ✅ | ✅ | ✅ 完成 |
| 文件下载 | ✅ | ✅ | ✅ 完成 |
| 编辑器方法调用 | ✅ | ✅ | ✅ 完成 |
| 生命周期管理 | ✅ | ✅ | ✅ 完成 |
| JWT 签名 | ✅ | ✅ | ✅ 完成 |
| 离线编辑 | ✅ | ❌ | 🔄 未来版本 |
| 协作编辑 | ✅ | ✅ | ✅ 由 DocsAPI 提供 |
| 插件系统 | ✅ | ⚠️ | 🔄 可通过 JS 实现 |
技术亮点
1. 状态暴露设计
将 _YxOnlyOfficeAdvancedViewerState 改为公开的 YxOnlyOfficeAdvancedViewerState,允许外部访问:
final GlobalKey<YxOnlyOfficeAdvancedViewerState> viewerKey = GlobalKey();
// 可以调用状态方法
await viewerKey.currentState!.insertImage(url);
2. 结果封装
使用 EditorMethodResult 统一封装方法调用结果:
final result = await viewerState.insertImage(url);
if (result.success) {
print('成功: ${result.data}');
} else {
print('失败: ${result.error}');
}
3. 回调链设计
支持多层回调处理:
// 方式 1: 使用内置处理器
onRequestImageFromGallery: () async {
return await pickAndUploadImage();
}
// 方式 2: 手动调用
await viewerState.insertImage(imageUrl);
4. 文件下载拦截
自动拦截下载 URL:
bool _isDownloadUrl(String url) {
return url.contains('/download') ||
url.contains('download=') ||
url.contains('outputtype=');
}
使用方式对比
基础版本(YxOnlyOfficeViewer)
YxOnlyOfficeViewer.create(
serverUrl: serverUrl,
fileUrl: fileUrl,
mode: 'edit',
onError: (error) => print(error),
)
适用于:
- 简单的文档查看/编辑
- 不需要高级控制
- 快速集成
高级版本(YxOnlyOfficeAdvancedViewer)
YxOnlyOfficeAdvancedViewer(
serverUrl: serverUrl,
config: config,
onControllerReady: (controller) {
// 完全控制 WebView
},
onDocumentReady: () {
// 文档准备好,可以调用方法
},
onRequestImageFromGallery: () async {
// 自定义图片选择
},
)
// 调用编辑器方法
await viewerState.insertImage(url);
await viewerState.downloadAs('pdf');
适用于:
- 需要完整控制编辑器
- 图片插入功能
- 文件下载处理
- 自定义 JavaScript 执行
- 高级编辑功能
运行示例
基础示例
flutter run \
--dart-define ONLYOFFICE_SERVER_URL=https://... \
--dart-define ONLYOFFICE_FILE_URL=https://...
高级示例
flutter run -t lib/main_advanced.dart \
--dart-define ONLYOFFICE_SERVER_URL=https://... \
--dart-define ONLYOFFICE_FILE_URL=https://... \
--dart-define ONLYOFFICE_JWT_SECRET=secret \
--dart-define UPLOAD_URL=https://...
未来改进方向
基于官方项目,以下功能可以在未来版本中添加:
-
离线编辑支持
- 本地文档缓存
- 离线修改同步
-
更多编辑器方法
- 插入表格
- 插入图表
- 插入书签
- 查找/替换
-
插件系统
- 支持 ONLYOFFICE 插件
- 自定义工具栏
-
性能优化
- 文档预加载
- 图片压缩
- 增量更新
-
协作功能增强
- 用户在线状态
- 实时光标显示
- 聊天功能
总结
通过深入研究官方 Android 和 iOS 项目,我们成功实现了:
✅ 完整的 WebView 桥接 - 实现 Flutter 与 DocsAPI 的双向通信 ✅ 编辑器方法调用 - 直接控制编辑器行为 ✅ 图片插入功能 - 完整的图片选择和插入流程 ✅ 文件下载处理 - 自动拦截和处理下载 ✅ 生命周期管理 - 完整的编辑器生命周期事件 ✅ 高质量示例 - 展示所有高级功能的使用
这个高级功能分支为 Flutter 开发者提供了与官方移动应用相当的功能和控制能力!🎉