如何使用Flutter和鸿蒙NEXT混合渲染

部署运行你感兴趣的模型镜像

前言导读

这一个节课我们讲一下PlatformView的是使用 我们在实战中有可能出现了在鸿蒙next只加载一部分Flutter的情况

我们今天就讲一下这种情况具体实现要使用到我们的PlatformView

效果图

1443c7f14349480f97a154bac944040

Native侧实现

  1. 使用 DevEco Studio工具打开 platform_view_example\ohos项目
  2. platform_view_example\ohos\entry\src\main\ets\entryability目录下实现代码
  3. 新建CustomView.ets文件,CustomView用于在Flutter Widget里显示

定义一个Component,代表ohos的PlatformView的定义

@Extend(TextInput) function  inputStyle(){
  .placeholderColor($r('app.color.placeholder_color'))
  .height(45)
  .fontSize(18)
  .backgroundColor($r('app.color.background'))
  .width('50%')
  .padding({left:10})
  .margin({left:100,top:0,right:50,bottom:0})
}

@Component
struct ButtonComponent {
  @Prop params: Params
  customView: CustomView = this.params.platformView as CustomView
  @StorageLink('numValue') storageLink: string = "first"
  @State bkColor: Color = Color.Red
  @State inputstr:string="";


  build() {
    Column() {
      Row(){
        TextInput({placeholder:'请输入你传递的参数'})
          .maxLength(10)
          .inputStyle()
          .onChange((value:string)=>{
            this.inputstr=value;
          }).margin({left:100,top:0,right:50,bottom:0})
      }.width('100%')
       .height(50)

      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(this.inputstr);
          console.log("nodeController button on click")
        }).margin({left:0,top:10,right:0,bottom:0})

      Text(`来自Flutter的数据 : ${this.storageLink}`).margin({left:0,top:10,right:0,bottom:0})
        .onTouch((event: TouchEvent) => {
         console.log("nodeController text on touched")
        })

    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .direction(Direction.Ltr)
    .width('100%')
    .height('100%')
  }
}

3.2 定义一个builder方法,放入3.1的自定义Component组件

@Builder
function ButtonBuilder(params: Params) {
  ButtonComponent({ params: params })
    .backgroundColor(Color.Yellow)
}

3.3 继承PlatformView实现一个自定义的Customview,实现getView接口,返回WrappedBuilder(ButtonBuilder),放入3.2的builder方法

AppStorage.setOrCreate('numValue', 'test')

@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();
    // 注册消息通道
    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 = (getinputstr:string) => {
    console.log("nodeController sendMessage")
    //向Dart侧发送消息
    this.methodChannel.invokeMethod('getMessageFromOhosView', 'natvie - ' + getinputstr);
  }

  getView(): WrappedBuilder<[Params]> {
    return new WrappedBuilder(ButtonBuilder);
  }

  dispose(): void {
  }
}

4 实现一个自定义的PlatformViewFactory,在其create方法中创建自定义的PlatformView的实例

import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
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 { CustomView } from './CustomView';
import common from '@ohos.app.ability.common';
import PlatformView from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView';



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);
  }
}

5 实现一个FlutterPlugin插件,在onAttachedToEngine中,注册自定义的PlatformViewFactory

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';
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    binding.getPlatformViewRegistry()?.
    registerViewFactory('com.rex.custom.ohos/customView', new CustomFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE));
  }

  onDetachedFromEngine(binding: FlutterPluginBinding): void {}
}

6 打开EntryAbility.ets文件,添加Plugin(也可以把自定义PlatformView写在一个鸿蒙插件中,在应用中沿用,就不用在此显式添加插件)

import { FlutterAbility } from '@ohos/flutter_ohos'
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine';
import { CustomPlugin } from './CustomPlugin';

export default class EntryAbility extends FlutterAbility {
  configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    GeneratedPluginRegistrant.registerWith(flutterEngine)
    this.addPlugin(new CustomPlugin());
  }
}

Flutter 端代码实现

1,使用 Android Studio工具打开 platform_view_example项目

2,在platform_view_example\lib目录下实现代码

3,新建CustomPage,用于显示Native侧的CustomView的Widget

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);

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: CustomExample(),
    );
  }
}
class CustomExample extends StatefulWidget {
  const CustomExample({Key? key}) : super(key: key);

  @override
  State<CustomExample> createState() => _CustomExampleState();
}

4,实现_CustomPageState

class _CustomExampleState extends State<CustomExample> {
  String receivedData = '';
  CustomViewController? _controller;

  String  toflutterStr='';

  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: [


              Row(
                children: <Widget>[
                  new Padding(padding: EdgeInsets.only(top: 0,left: 30.0,right: 0,bottom: 0)),
                  Container(
                    alignment: Alignment.center,
                    width: 100,
                    height: 50,
                    child: Text("Flutter到鸿蒙:"),
                  ),
                  Expanded(
                    child: TextField(
                      obscureText: false,
                      decoration: InputDecoration(
                        hintText: "请输入要传递的参数",
                        border: InputBorder.none,
                      ),
                      onChanged: (value){
                        setState(() {
                          this.toflutterStr=value;
                        });
                      },
                    ),
                  )
                ],
              ),

              ElevatedButton(
                onPressed: () {
                  final randomNum = Random().nextInt(10);
                  _controller
                      ?.sendMessageToOhosView(this.toflutterStr);
                },
                child: const Text('发送数据给鸿蒙next'),
              ),
              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,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        _buildOhosView(),
        _buildFlutterView(),
      ],
    );
  }
}

OhosView组件就是桥接PlatformView的关键。

  • viewType:传递给鸿蒙next Native 端,告知插件需要创建那个PlatformView,这个PlatformView需要在插件初始化时注册。
  • onPlatformViewCreated:PlatformView创建成功时的回调。
  • creationParams:传递给PlatformView的初始化参数。

5、实现CustomOhosView,使用OhosView组件,viewType需要和ets侧FlutterPluginregisterViewFactory操作时指定的viewType一致

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

typedef OnViewCreated = Function(CustomViewController);

//自定义OhosView
class 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);
  }
}

6、新建CustomViewController,用于实现flutter端与鸿蒙next端的交互

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;

  // 发送数据给native
  Future<void> sendMessageToOhosView(String message) async {
    await _channel.invokeMethod(
      'getMessageFromFlutterView',
      message,
    );
  }
}

编译运行

一、签名

1,使用 DevEco Studio工具打开 platform_view_example\ohos目录

2,单击 File > Project Structure > Project > Signing Configs界面勾选 Automatically generate signature,等待自动签名完成,点击OK

二、编译运行

1,cdplatform_view_example 目录下

2,打开 终端,执行下面指令进行编译运行:

flutter run -d <device-id>

第二种运行方式直接直接输入

image-20240720193444438

flutter build hap

然后直接使用 DevEco Studio工具打开 platform_view_example\ohos目录 然后使用 DevEco Studio 运行项目也可以

image-20240720193559056

需要注意的点

这里最好使用真机运行 如果是windows 电脑的x86架构的模拟器运行会报错

最后总结

我们使用 PlatformView 就可以实现在我们鸿蒙native 项目中只需要加载部分的Flutter项目比较类似安卓的里面只加载一个view或者是fragment。

也可以配合我们之前讲的章节能够在实战中很好使用Flutter在我们的鸿蒙next上面跨端的开发。也可以很好使用上面原本Flutter项目上已有的一些功能

减少开发适配鸿蒙的一个成本。

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

<think>好的,我需要帮助用户了解Flutter鸿蒙系统的混合开发方法教程。首先,我得看看用户提供的参考引用,里面提到了几个相关的资源,可能需要从中提取关键步骤方法。 根据引用[2],用户需要安装鸿蒙Flutter环境,这可能包括配置开发环境必要的工具。然后引用[3]提到了使用ArkTs开发Flutter鸿蒙插件,涉及到MethodChannel的通信,这部分是关键步骤。此外,引用[4]提到创建package的方法,这可能涉及到如何将Flutter模块集成到鸿蒙项目中。 接下来,我需要将这些信息整合成一个清晰的步骤指南。首先应该是环境配置,然后是如何创建插件,处理通信,最后是打包集成。同时,用户可能还需要了解性能优化实际应用场景,所以在相关问题上可以提出性能优化或应用场景的问题。 需要注意的是,用户提供的引用中有一些可能不太相关的内容,比如引用[1]提到的好处视频详解,但其他引用更具体,所以重点放在环境安装、插件开发通信机制上。确保步骤准确,并且每个部分都引用正确的来源。 最后,生成相关问题时要围绕混合开发的方法、性能优化、通信机制等,帮助用户进一步探索。检查是否有遗漏的步骤,或者是否有更详细的信息需要补充,比如具体的代码示例或配置文件的修改。</think>### Flutter鸿蒙系统混合开发方法详解 #### 一、环境配置 1. **安装Flutter鸿蒙开发环境** 需同时安装Flutter SDK鸿蒙DevEco Studio开发工具。在Flutter项目中添加鸿蒙平台支持,通过以下命令初始化鸿蒙模块: ```bash flutter create --platforms=harmony . ``` 此步骤会生成鸿蒙模块的基础代码结构[^4]。 2. **配置鸿蒙插件依赖** 在鸿蒙工程的`build.gradle`中添加Flutter模块依赖: ```gradle dependencies { implementation project(':flutter') } ``` 确保Flutter模块与鸿蒙主工程的路径正确映射[^2]。 --- #### 二、插件开发与通信机制 1. **Flutter侧代码** 使用`MethodChannel`定义通信接口,例如数据存储功能: ```dart const MethodChannel _methodChannel = MethodChannel('com.example.app/data'); static Future<String> getToken() async { return await _methodChannel.invokeMethod('getPrefs', 'token'); } ``` 此代码通过通道名`com.example.app/data`与鸿蒙原生代码交互[^3]。 2. **鸿蒙侧代码(ArkTS)** 在鸿蒙端实现`MethodChannel`对应的逻辑: ```typescript import { Ability, methodChannel, MethodResult } from '@ohos.ability.feature'; export default class MainAbility extends Ability { onConnect() { methodChannel.registerHandler('com.example.app/data', 'getPrefs', (key) => { return Preferences.get(this.context, key); //从本地存储读取数据 }); } } ``` 此处通过`Preferences`实现数据持久化,与Flutter侧方法一一对应。 --- #### 三、混合工程打包 1. **构建Flutter产物** 执行命令生成鸿蒙平台的编译文件: ```bash flutter build harmony ``` 输出产物位于`build/harmony/`目录,包含HAP(鸿蒙应用包)所需的资源文件[^4]。 2. **集成到鸿蒙主工程** 将生成的`libflutter.so`Dart代码打包到HAP中,通过DevEco Studio的`config.json`添加权限: ```json { "module": { "abilities": [ { "name": ".MainAbility", "srcEntrance": "./ets/MainAbility.ts" } ], "requestPermissions": [ { "name": "ohos.permission.FILE_READ_WRITE" } //文件读写权限 ] } } ``` 此配置确保Flutter插件功能正常调用系统API。 --- #### 四、调试与优化建议 1. **日志联调** 同时查看Flutter的`print()`输出鸿蒙的`HiLog`日志,需在DevEco Studio中过滤`FlutterPlugin`标签。 2. **性能优化** - **渲染优化**:对复杂UI使用鸿蒙的`XComponent`进行原生渲染[^1] - **内存管理**:通过`@State``@Link`装饰器减少跨平台数据拷贝 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚果的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值