一、背景介绍
在跨平台开发中,Flutter 通过 PlatformView 机制允许开发者嵌入原生平台的视图组件。对于鸿蒙(HarmonyOS)系统,同样可以通过类似机制实现 Flutter 与原生组件的无缝整合。本文将介绍如何在 Flutter 应用中嵌入鸿蒙原生视图,并实现双向通信。
二、 PlatformView 机制
Flutter 通过 PlatformView 接口将原生视图渲染到 Flutter 的 widget 树中。对于鸿蒙系统,我们需要:
1、创建鸿蒙原生组件:使用 Java/JS 编写 HarmonyOS 的 UI 组件。
2、建立通信桥梁:通过 MethodChannel 实现 Flutter 与原生端的双向通信。
2、处理布局与生命周期:协调 Flutter 与原生视图的布局和渲染。
三、实现步骤
1、创建 Flutter 插件项目:
flutter create --template=plugin harmony_view
2、鸿蒙原生端实现
使用 DevEco Studio工具打开 harmony_view\ohos项目,在harmony_view\ohos\entry\src\main\ets\entryability目录下实现代码
2.1、新建CustomView.ets文件,CustomView用于在Flutter Widget里显示
@Componentstruct ButtonComponent {@Prop params: ParamscustomView: CustomView = this.params.platformView as CustomView@StorageLink('numValue') storageLink: string = "first"@State bkColor: Color = Color.Redbuild() {Column() {Button("发送数据给Flutter").border({ width: 2, color: Color.Blue}).backgroundColor(this.bkColor).onTouch((event: TouchEvent) => {console.log("nodeController button on touched")}).onClick((event: ClickEvent) => {this.customView.sendMessage();console.log("nodeController button on click")})Text(`来自Flutter的数据 : ${this.storageLink}`).onTouch((event: TouchEvent) => {console.log("nodeController text on touched")})}.alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center).direction(Direction.Ltr).width('100%').height('100%')}}
2.2、定义一个builder方法,放入2.1的自定义Component组件
@Builderfunction ButtonBuilder(params: Params) {ButtonComponent({ params: params }).backgroundColor(Color.Yellow)}
2.3、继承PlatformView实现一个自定义的Customview,实现getView接口,返回WrappedBuilder(ButtonBuilder),放入2.2的的builder方法
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';@Observedexport 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("nodeController viewId:" + viewId)// 注册消息通道,消息通道根据具体需求添加,代码仅作为示例this.methodChannel = new MethodChannel(message, `com.rex.custom.ohos/customView${viewId}`, StandardMethodCodec.INSTANCE);this.methodChannel.setMethodCallHandler(this);}onMethodCall(call: MethodCall, result: MethodResult): void {// 接受Dart侧发来的消息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("nodeController receive message from dart: " + this.numValue);result.success(true);break;}}public sendMessage = () => {console.log("nodeController sendMessage")//向Dart侧发送消息this.methodChannel.invokeMethod('getMessageFromOhosView', 'natvie - ' + this.index++);}getView(): WrappedBuilder<[Params]> {return new WrappedBuilder(ButtonBuilder);}dispose(): void {}}
2.4、实现一个自定义的PlatformViewFactory,在其create方法中创建自定义的PlatformView的实例
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;}public create(context: common.Context, viewId: number, args: Object): PlatformView {return new CustomView(context, viewId, args, this.message);}}
1.5、新建一个继承于FlutterPlugin的CustomPlugin插件,在onAttachedToEngine中,注册自定义的PlatformViewFactory
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());
}
}
3、Flutter 端实现
用AndroidStudio工具打开harmony_view项目在harmony_view\lib目录下实现代码,新建CustomOhosView.dart,用于显示Native侧的CustomView的Widget OhosView组件就是桥接PlatformView的关键。
-
viewType:传递给Native侧,告知插件需要创建那个PlatformView,这个PlatformView需要在插件初始化时注册。
-
onPlatformViewCreated:PlatformView创建成功时的回调。
-
creationParams:传递给PlatformView的初始化参数。
3.1、实现CustomOhosView,使用OhosView组件,viewType需要和ets侧FlutterPlugin做registerViewFactory操作时指定的viewType一致
import 'dart:async'; import 'package:flutter/material.dart';import 'package:flutter/services.dart'; typedef OnViewCreated = Function(CustomViewController); ///自定义OhosViewclass CustomOhosView extends StatefulWidget { final OnViewCreated onViewCreated; const CustomOhosView(this.onViewCreated, {Key? key}) : super(key: key); @override State<CustomOhosView> createState() => _CustomOhosViewState();} class _CustomOhosViewState extends State<CustomOhosView> { late MethodChannel _channel; @override Widget build(BuildContext context) { return _getPlatformFaceView(); } Widget _getPlatformFaceView() { return OhosView( viewType: 'com.rex.custom.ohos/customView', onPlatformViewCreated: _onPlatformViewCreated, creationParams: const <String, dynamic>{'initParams': 'hello world'}, creationParamsCodec: const StandardMessageCodec(), ); } void _onPlatformViewCreated(int id) { _channel = MethodChannel('com.rex.custom.ohos/customView$id'); final controller = CustomViewController._( _channel, ); widget.onViewCreated(controller); }}
3.2、在CustomOhosView所在文件中新建CustomViewController,用于实现Dart侧与Native侧的交互
class CustomViewController {final MethodChannel _channel;final StreamController<String> _controller = StreamController<String>();CustomViewController._(this._channel,) {_channel.setMethodCallHandler((call) async {switch (call.method) {case 'getMessageFromOhosView':// 从native端获取数据final result = call.arguments as String;_controller.sink.add(result);break;}},);}Stream<String> get customDataStream => _controller.stream;// 发送数据给nativeFuture<void> sendMessageToOhosView(String message) async {await _channel.invokeMethod('getMessageFromFlutterView',message,);}}
3.3、修改harmony_view\lib\main.dart文件中的代码写测试
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);@overrideWidget build(BuildContext context) {return const Scaffold(body: CustomExample(),);}}class CustomExample extends StatefulWidget {const CustomExample({Key? key}) : super(key: key);@overrideState<CustomExample> createState() => _CustomExampleState();}class _CustomExampleState extends State<CustomExample> {String receivedData = '';CustomViewController? _controller;void _onCustomOhosViewCreated(CustomViewController controller) {_controller = controller;_controller?.customDataStream.listen((data) {//接收到来自OHOS端的数据setState(() {receivedData = '来自ohos的数据:$data';});});}Widget _buildOhosView() {return Expanded(child: Container(color: Colors.blueAccent.withAlpha(60),child: CustomOhosView(_onCustomOhosViewCreated),),flex: 1,);}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('发送数据给ohos'),),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,);}@overrideWidget build(BuildContext context) {return Column(children: [_buildOhosView(),_buildFlutterView(),],);}}
四、总结
通过 PlatformView 集成鸿蒙原生视图,开发者可以:
-
保留 Flutter 跨平台优势
-
充分利用鸿蒙系统特性
-
实现渐进式混合开发
未来随着 HarmonyOS 生态的发展,这种混合开发模式将显著提升应用的功能扩展能力。
1086

被折叠的 条评论
为什么被折叠?



