Flutter跨平台PlatformView鸿蒙化使用指南
Flutter PlatformView技术为OpenHarmony平台开发提供了原生组件嵌入能力,实现了Flutter与鸿蒙UI的无缝集成。本文详细介绍了该技术的核心功能、环境配置和实现方法

一、功能介绍
PlatformView是Flutter跨平台开发中的一项核心技术,它允许Flutter应用嵌入和使用原生平台的UI组件。在OpenHarmony平台上,PlatformView为Flutter开发者提供了访问鸿蒙原生能力的桥梁,实现了Flutter与OpenHarmony原生组件的无缝集成。
1.1 核心特性
- 原生组件嵌入:在Flutter界面中直接使用OpenHarmony原生UI组件
- 双向通信:支持Flutter与原生组件之间的消息传递
- 生命周期管理:自动处理原生组件的创建、更新和销毁
- 跨平台兼容:保持Flutter代码的跨平台特性,同时利用平台特定功能
1.2 技术依赖
- OpenHarmony API 20及以上版本
- Flutter SDK 3.27.5-ohos-1.0.0及以上版本
- DevEco Studio 5.0.5+(用于OpenHarmony原生开发)
1.3 适用场景
- 需要使用特定OpenHarmony原生UI组件的场景
- 需要调用OpenHarmony平台特定API的功能
- 性能敏感的原生组件(如地图、视频播放器等)
- 已有的OpenHarmony原生组件需要复用的情况
二、环境准备
2.1 开发工具
- DevEco Studio:版本5.0.5 Release及以上
- 下载地址:https://developer.huawei.com/consumer/cn/download/deveco-studio
- JDK:版本17
- Node.js:版本16及以上
2.2 Flutter SDK
需要使用支持OpenHarmony PlatformView的Flutter SDK,具体要求:
- 版本:3.27.5-ohos-1.0.0及以上
- 分支:3.27.5-ohos-1.0.0
- 获取地址:https://atomgit.com/openharmony-tpc/flutter_flutter/tree/3.27.5-ohos-1.0.0
2.3 环境变量配置
# Flutter环境变量
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PATH=/path/to/flutter_flutter/bin:$PATH
# OpenHarmony环境变量
export OHOS_HOME=/path/to/ohos/ohos-sdk
2.4 验证环境
配置完成后,执行以下命令验证环境:
# 验证Flutter版本
flutter --version
# 验证Flutter环境
flutter doctor -v
三、包的引入与配置
3.1 创建Flutter项目
使用以下命令创建支持OpenHarmony平台的Flutter项目:
flutter create --platforms ohos platform_demo
cd platform_demo
flutter pub get
3.2 项目结构
创建完成后,项目将包含以下主要目录:
lib/:Flutter Dart代码目录ohos/:OpenHarmony原生代码目录entry/src/main/ets/:OpenHarmony ArkTS代码
四、API调用和使用示例
4.1 原生侧实现(ArkTS)
4.1.1 创建自定义View组件
在platform_demo/ohos/entry/src/main/ets/entryability目录下创建CustomView.ets文件:
import MethodChannel, {
MethodCallHandler,
MethodResult
} from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel';
import PlatformView, { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView';
import common from '@ohos.app.ability.common';
import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
import StandardMethodCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec';
import MethodCall from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall';
// 自定义组件,用于在Flutter中显示
@Component
struct ButtonComponent {
@Prop params: Params
customView: CustomView = this.params.platformView as CustomView
@StorageLink('numValue') storageLink: string = "first"
@State bkColor: Color = Color.Red
build() {
Column() {
Button("发送数据给Flutter")
.border({ width: 2, color: Color.Blue})
.backgroundColor(this.bkColor)
.onClick((event: ClickEvent) => {
this.customView.sendMessage();
console.log("OpenHarmony按钮被点击")
})
Text(`来自Flutter的数据 : ${this.storageLink}`)
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
}
}
// Builder方法,用于构建自定义组件
@Builder
function ButtonBuilder(params: Params) {
ButtonComponent({ params: params })
.backgroundColor(Color.Yellow)
}
// 自定义PlatformView实现
@Observed
export class CustomView extends PlatformView implements MethodCallHandler {
numValue: string = "test";
methodChannel: MethodChannel;
index: number = 1;
constructor(context: common.Context, viewId: number, args: ESObject, message: BinaryMessenger) {
super();
console.log("CustomView初始化,viewId:" + viewId)
// 注册消息通道
this.methodChannel = new MethodChannel(message, `com.rex.custom.ohos/customView${viewId}`, StandardMethodCodec.INSTANCE);
this.methodChannel.setMethodCallHandler(this);
}
// 处理来自Flutter的方法调用
onMethodCall(call: MethodCall, result: MethodResult): void {
let method: string = call.method;
let link1: SubscribedAbstractProperty<number> = AppStorage.link('numValue');
switch (method) {
case 'getMessageFromFlutterView':
let value: ESObject = call.args;
this.numValue = value;
link1.set(value)
console.log("收到Flutter消息: " + this.numValue);
result.success(true);
break;
default:
result.notImplemented();
break;
}
}
// 向Flutter发送消息
public sendMessage = () => {
console.log("向Flutter发送消息")
this.methodChannel.invokeMethod('getMessageFromOhosView', 'native - ' + this.index++);
}
// 返回自定义组件的Builder
getView(): WrappedBuilder<[Params]> {
return new WrappedBuilder(ButtonBuilder);
}
dispose(): void {
// 清理资源
}
}
4.1.2 创建PlatformView工厂
在同一目录下创建CustomFactory.ets文件:
import common from '@ohos.app.ability.common';
import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec';
import PlatformViewFactory from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory';
import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
import PlatformView from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView';
import { CustomView } from './CustomView';
export class CustomFactory extends PlatformViewFactory {
message: BinaryMessenger;
constructor(message: BinaryMessenger, createArgsCodes: MessageCodec<Object>) {
super(createArgsCodes);
this.message = message;
}
// 创建PlatformView实例
public create(context: common.Context, viewId: number, args: Object): PlatformView {
return new CustomView(context, viewId, args, this.message);
}
}
4.1.3 创建Flutter插件
在同一目录下创建CustomPlugin.ets文件:
import { FlutterPlugin, FlutterPluginBinding } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin';
import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec';
import { CustomFactory } from './CustomFactory';
export class CustomPlugin implements FlutterPlugin {
getUniqueClassName(): string {
return 'CustomPlugin';
}
// 插件初始化时注册PlatformView工厂
onAttachedToEngine(binding: FlutterPluginBinding): void {
binding.getPlatformViewRegistry()?.registerViewFactory('com.rex.custom.ohos/customView', new CustomFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE));
}
onDetachedFromEngine(binding: FlutterPluginBinding): void {
// 插件卸载时清理
}
}
4.1.4 注册插件
修改EntryAbility.ets文件,注册自定义插件:
import { FlutterAbility } from '@ohos/flutter_ohos'
import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine';
import { CustomPlugin } from './CustomPlugin';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
export default class EntryAbility extends FlutterAbility {
configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
this.addPlugin(new CustomPlugin()); // 注册自定义插件
}
}
4.2 Flutter侧实现(Dart)
4.2.1 创建CustomOhosView组件
在platform_demo/lib目录下创建custom_ohos_view.dart文件:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
typedef OnViewCreated = Function(CustomViewController);
/// 自定义OpenHarmony View组件
class CustomOhosView extends StatefulWidget {
final OnViewCreated onViewCreated;
const CustomOhosView(this.onViewCreated, {Key? key}) : super(key: key);
State<CustomOhosView> createState() => _CustomOhosViewState();
}
class _CustomOhosViewState extends State<CustomOhosView> {
late MethodChannel _channel;
Widget build(BuildContext context) {
return _getPlatformFaceView();
}
Widget _getPlatformFaceView() {
return OhosView(
viewType: 'com.rex.custom.ohos/customView', // 与原生侧注册的viewType一致
onPlatformViewCreated: _onPlatformViewCreated,
creationParams: const <String, dynamic>{'initParams': 'hello world'},
creationParamsCodec: const StandardMessageCodec(),
);
}
// PlatformView创建完成回调
void _onPlatformViewCreated(int id) {
_channel = MethodChannel('com.rex.custom.ohos/customView$id');
final controller = CustomViewController._(
_channel,
);
widget.onViewCreated(controller);
}
}
/// CustomView控制器,用于与原生组件通信
class CustomViewController {
final MethodChannel _channel;
final StreamController<String> _controller = StreamController<String>();
CustomViewController._(
this._channel,
) {
// 监听来自原生的消息
_channel.setMethodCallHandler(
(call) async {
switch (call.method) {
case 'getMessageFromOhosView':
// 处理来自OpenHarmony的消息
final result = call.arguments as String;
_controller.sink.add(result);
break;
}
},
);
}
// 获取数据流
Stream<String> get customDataStream => _controller.stream;
// 向OpenHarmony发送消息
Future<void> sendMessageToOhosView(String message) async {
await _channel.invokeMethod(
'getMessageFromFlutterView',
message,
);
}
}
4.2.2 主应用实现
修改lib/main.dart文件,集成CustomOhosView:
import 'dart:math';
import 'package:flutter/material.dart';
import 'custom_ohos_view.dart';
void main() {
runApp(const MaterialApp(home: MyHome()));
}
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const Scaffold(
body: CustomExample(),
);
}
}
class CustomExample extends StatefulWidget {
const CustomExample({Key? key}) : super(key: key);
State<CustomExample> createState() => _CustomExampleState();
}
class _CustomExampleState extends State<CustomExample> {
String receivedData = '';
CustomViewController? _controller;
// 自定义View创建完成回调
void _onCustomOhosViewCreated(CustomViewController controller) {
_controller = controller;
// 监听来自原生的消息
_controller?.customDataStream.listen((data) {
setState(() {
receivedData = '来自OpenHarmony的数据:$data';
});
});
}
// 构建OpenHarmony原生View
Widget _buildOhosView() {
return Expanded(
child: Container(
color: Colors.blueAccent.withAlpha(60),
child: CustomOhosView(_onCustomOhosViewCreated),
),
flex: 1,
);
}
// 构建Flutter View
Widget _buildFlutterView() {
return Expanded(
child: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
TextButton(
onPressed: () {
final randomNum = Random().nextInt(10);
_controller
?.sendMessageToOhosView('flutter - $randomNum');
},
child: const Text('发送数据给OpenHarmony'),
),
const SizedBox(height: 10),
Text(receivedData),
],
),
const Padding(
padding: EdgeInsets.only(bottom: 15),
child: Text(
'Flutter View',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
],
),
flex: 1,
);
}
Widget build(BuildContext context) {
return Column(
children: [
_buildOhosView(),
_buildFlutterView(),
],
);
}
}
五、编译运行和验证方法
5.1 签名配置
- 使用DevEco Studio打开
platform_demo/ohos项目 - 点击
File > Project Structure > Project > Signing Configs - 勾选
Automatically generate signature,等待自动签名完成 - 点击OK保存配置
5.2 编译运行
- 连接OpenHarmony设备或启动模拟器
- 打开终端,进入项目目录
- 执行以下命令运行应用:
flutter run -d <device-id>
5.3 功能验证
应用运行后,可以进行以下验证:
-
界面布局:
- 上半部分为OpenHarmony原生组件(黄色背景)
- 下半部分为Flutter组件(蓝色背景)
-
消息传递:
- 点击OpenHarmony端的"发送数据给Flutter"按钮,观察Flutter端是否显示收到的数据
- 点击Flutter端的"发送数据给OpenHarmony"按钮,观察OpenHarmony端是否显示收到的数据
-
组件交互:
- 验证原生组件的点击事件是否正常响应
- 验证Flutter与原生组件之间的通信是否流畅
六、常见问题与解决方案
6.1 PlatformView创建失败
问题:应用运行时出现"PlatformView creation failed"错误
解决方案:
- 确保
viewType在Flutter侧和OpenHarmony侧完全一致 - 检查OpenHarmony插件是否正确注册
- 验证Flutter SDK版本是否支持PlatformView
6.2 消息通信失败
问题:Flutter与OpenHarmony之间的消息传递失败
解决方案:
- 检查MethodChannel的名称是否正确
- 确保消息编解码器一致(使用StandardMessageCodec)
- 检查方法名称是否匹配
6.3 组件显示异常
问题:PlatformView显示异常或不显示
解决方案:
- 确保CustomView正确实现了getView方法
- 检查Builder方法是否正确构建组件
- 验证组件尺寸设置是否合理
6.4 编译错误
问题:编译时出现"Undefined symbol"或"Class not found"错误
解决方案:
- 检查依赖导入路径是否正确
- 确保所有必要的库都已正确引用
- 验证Flutter和OpenHarmony SDK版本兼容性
七、总结
PlatformView是Flutter在OpenHarmony平台上实现原生组件集成的核心技术,它为开发者提供了访问原生能力的强大工具。通过本文的介绍,开发者可以了解到:
- PlatformView的核心概念:实现Flutter与OpenHarmony原生组件的无缝集成
- 完整的实现流程:从环境配置到代码实现的全流程指导
- 双向通信机制:Flutter与OpenHarmony之间的消息传递方法
- 实际应用示例:完整的代码示例展示了PlatformView的具体使用
合理使用PlatformView可以充分发挥Flutter的跨平台优势和OpenHarmony的原生能力,为用户提供更加丰富和高效的应用体验。
八、社区支持
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
在社区中,您可以获取最新的技术资讯、交流开发经验、解决技术问题,与其他开发者共同推动OpenHarmony跨平台生态的发展。
更多推荐



所有评论(0)