当前位置: 首页 > news >正文

Flutter中PlatformView在鸿蒙中的使用

Flutter中PlatformView在鸿蒙中的使用

  • 概述
  • 在Flutter中的处理
  • 鸿蒙端
    • 创建内嵌的鸿蒙视图
    • 创建PlatformView
    • 创建PlatformViewFactory
    • 创建plugin,注册platformview
    • 注册插件

概述

集成平台视图(后称为平台视图)允许将原生视图嵌入到 Flutter 应用中,所以你可以通过 Dart 将变换、裁剪和不透明度等效果应用到原生视图。

例如,这使你可以通过使用平台视图直接在 Flutter 应用内部使用鸿蒙中的原生地图。

在Flutter中的处理

首先我们需要再Flutter中创建一个视图,用来加载Ohos平台的view。

import 'dart:async';import 'package:flutter/material.dart';
import 'package:flutter/services.dart';typedef OnViewCreated = Function(CustomViewController);class CustomOhosView extends StatefulWidget {final OnViewCreated onViewCreated;const CustomOhosView(this.onViewCreated, {super.key});State<CustomOhosView> createState() => _CustomOhosViewState();
}class _CustomOhosViewState extends State<CustomOhosView> {late MethodChannel _channel;Widget build(BuildContext context) {return _getPlatformFaceView();}Widget _getPlatformFaceView() {// 加载platformview/*** viewType:传递给Native侧,告知插件需要创建那个PlatformView,这个PlatformView需要在插件初始化时注册。onPlatformViewCreated:PlatformView创建成功时的回调。creationParams:传递给PlatformView的初始化参数。*/return OhosView(viewType: 'com.rex.custom.ohos/customView',onPlatformViewCreated: _onPlatformViewCreated,creationParams: const <String, dynamic>{'initParams': 'hello world'},creationParamsCodec: const StandardMessageCodec(),);}void _onPlatformViewCreated(int id) {print("platformview==================创建成功");_channel = MethodChannel('com.rex.custom.ohos/customView$id');final controller = CustomViewController._(_channel,);widget.onViewCreated(controller);}
}// 用于实现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,);}
}

鸿蒙端

创建内嵌的鸿蒙视图

该视图就是我们ohos平台中的组件, 示例代码如下:

@Component
export struct PlatformView_Custom {@Prop params: Params// customView: video_Customview = this.params.platformView as video_Customviewbuild() {Column() {Column() {Button("测试按钮").onClick(() => {console.log("点击按钮时间")})}.backgroundColor(Color.Orange).height('230vp').width('100%').justifyContent(FlexAlign.End)}.backgroundColor(Color.Pink).width('100%').height('100%')}
}

注意:PlatformView_Custom 嵌入到Flutter页面中时, 系统实际上是在我们的这个组件又包裹了一层空间, 并且默认是充满Flutter父空间的全部空间。

创建PlatformView

我们需要创建一个PlatformView的子类,并实现并且实现MethodCallHandler接口。

该类有两个作用:

  1. 通过类中的getView(): WrappedBuilder<[Params]>{}方法把上面创建的鸿蒙组件加载到这个PlatformView上
  2. 实现MethodCallHandler接口, 负责和Flutter的相关通信

示例代码如下:

/*** @ProjectName : ohos* @FileName : PlatformView_plugin* @Author : issuser* @Time : 2024/10/11 9:33* @Description : 文件描述*/
import {BinaryMessenger,MethodCall, MethodCallHandler, MethodChannel, MethodResult, PlatformView,StandardMethodCodec } from '@ohos/flutter_ohos';
import { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView';
import { PlatformView_Custom } from './PlatformView_Custom';
import { common } from '@kit.AbilityKit';export class PlatformView_plugin 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/video_CustomView${viewId}`, StandardMethodCodec.INSTANCE);// 给通道添加监听this.methodChannel.setMethodCallHandler(this);}// 实现onMethodCall接口onMethodCall(call: MethodCall, result: MethodResult): void {// 接受Dart侧发来的消息let method: string = call.method;let link1: SubscribedAbstractProperty<number> = AppStorage.link('numValue');switch (method) {case 'video_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;}}//  返回鸿蒙要展示的视图getView(): WrappedBuilder<[Params]> {return new WrappedBuilder(platformBuilder)}// 生命周期方法 销毁时dispose(): void {throw new Error('Method not implemented.');}}// 全局的build函数,通过这个bbuilder函数返回我们的组件view
@Builder
function platformBuilder(param: Params) {PlatformView_Custom({params: param}).backgroundColor(Color.Green)
}

创建PlatformViewFactory

PlatformView类的创建是通过PlatformViewFactory来创建, 所以我们需要创建一个工厂类继承自PlatformViewFactory

示例代码:

// 通过工厂方法创建一个plaugin示例
export class CustomFactory extends PlatformViewFactory {message: BinaryMessenger;constructor(message: BinaryMessenger, createArgsCodes: MessageCodec<Object>) {super(createArgsCodes);this.message = message;}public create(context: Context, viewId: number, args: Object): PlatformView {return new PlatformView_plugin(context, viewId, args, this.message);}
}

创建plugin,注册platformview

新建一个继承于FlutterPluginCustomPlugin插件,在onAttachedToEngine中,注册自定义的PlatformViewFactory

示例代码:

import { StandardMessageCodec } from '@ohos/flutter_ohos';
import {FlutterPlugin,FlutterPluginBinding
} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin';
import { CustomFactory } from './CustomFactory';export class CustomPlugin implements FlutterPlugin {getUniqueClassName(): string {return 'CustomPlugin'}// 当插件挂载到引擎上时onAttachedToEngine(binding: FlutterPluginBinding): void {// 在插件挂在在引擎的时候, 我们需要注册我们的viewbinding.getPlatformViewRegistry()?.registerViewFactory('com.rex.custom.ohos/customView',new CustomFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE));}onDetachedFromEngine(binding: FlutterPluginBinding): void {throw new Error('Method not implemented.');}
}

注册插件

在EntryAblitity中注册我们创建的自定义插件:

export default class EntryAbility extends FlutterAbility {configureFlutterEngine(flutterEngine: FlutterEngine) {super.configureFlutterEngine(flutterEngine)GeneratedPluginRegistrant.registerWith(flutterEngine)// 注册platformview的自定义插件this.addPlugin(new CustomPlugin());}
}

然后执行flutter build hap命令进行编译, 配置相关证书, 运行。

相关文章:

Flutter中PlatformView在鸿蒙中的使用

Flutter中PlatformView在鸿蒙中的使用 概述在Flutter中的处理鸿蒙端创建内嵌的鸿蒙视图创建PlatformView创建PlatformViewFactory创建plugin&#xff0c;注册platformview注册插件 概述 集成平台视图&#xff08;后称为平台视图&#xff09;允许将原生视图嵌入到 Flutter 应用…...

音频入门(一):音频基础知识与分类的基本流程

音频信号和图像信号在做分类时的基本流程类似&#xff0c;区别就在于预处理部分存在不同&#xff1b;本文简单介绍了下音频处理的方法&#xff0c;以及利用深度学习模型分类的基本流程。 目录 一、音频信号简介 1. 什么是音频信号 2. 音频信号长什么样 二、音频的深度学习分…...

规避路由冲突

路由冲突是指在网络中存在两个或多个路由器在进行路由选择时出现矛盾&#xff0c;导致网络数据包无法正确传输&#xff0c;影响网络的正常运行。为了规避路由冲突&#xff0c;可以采取以下措施&#xff1a; 一、合理规划IP地址 分配唯一IP&#xff1a;确保每个设备在网络中都有…...

SQLmap 自动注入 -02

1: 如果想获得SQL 数据库的信息&#xff0c;可以加入参数: -dbs sqlmap -u "http://192.168.56.133/mutillidae/index.php?pageuser-info.php&usernamexiaosheng&passwordabc&user-info-php-submit-buttonViewAccountDetails" --batch -p username -dbs…...

4.JoranConfigurator解析logbak.xml

文章目录 一、前言二、源码解析GenericXMLConfiguratorlogback.xml解析通过SaxEvent构建节点model解析model节点DefaultProcessor解析model 三、总结 一、前言 上一篇介绍了logback模块解析logback.mxl文件的入口, 我们可以手动指定logback.xml文件的位置, 也可以使用其它的名…...

React 19 新特性总结

具体详见官网&#xff1a; 中文&#xff1a;React 19 新特性 英文&#xff1a;React 19 新特性 核心新特性 1. Actions 解决问题&#xff1a;简化数据变更和状态更新流程 以前需要手动处理待定状态、错误、乐观更新和顺序请求需要维护多个状态变量(isPending, error 等) 新…...

kafka学习笔记6 ACL权限 —— 筑梦之路

在Kafka中&#xff0c;ACL&#xff08;Access Control List&#xff09;是用来控制谁可以访问Kafka资源&#xff08;如主题、消费者组等&#xff09;的权限机制。ACL配置基于Kafka的kafka-acls.sh工具&#xff0c;能够管理对资源的读取、写入等操作权限。 ACL介绍 Kafka的ACL是…...

【Java】Java抛异常到用户界面公共封装

前言 在Java中处理代码运行异常是常见的技术点之一&#xff0c;我们大部分会使用封装的技巧将异常进行格式化输出&#xff0c;方便反馈给用户界面&#xff0c;也是为了代码复用 看看这行代码是怎么处理异常的 CommonExceptionType.SimpleException.throwEx("用户信息不…...

基于Redis实现短信验证码登录

目录 1 基于Session实现短信验证码登录 2 配置登录拦截器 3 配置完拦截器还需将自定义拦截器添加到SpringMVC的拦截器列表中 才能生效 4 Session集群共享问题 5 基于Redis实现短信验证码登录 6 Hash 结构与 String 结构类型的比较 7 Redis替代Session需要考虑的问题 8 …...

步入响应式编程篇(二)之Reactor API

步入响应式编程篇&#xff08;二&#xff09;之Reactor API 前言回顾响应式编程Reactor API的使用Stream引入依赖Reactor API的使用流源头的创建 reactor api的背压模式发布者与订阅者使用的线程查看弹珠图查看形成新流的日志 前言 对于响应式编程的基于概念&#xff0c;以及J…...

Oracle SQL: TRANSLATE 和 REGEXP_LIKE 的知识点详细分析

目录 前言1. TRANSLATE2. REGEXP_LIKE3. 实战 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 1. TRANSLATE TRANSLATE 用于替换字符串中指定字符集的每个字符&#xff0c;返回替换后的字符串 逐一映射输入字…...

RabbitMQ 在实际应用时要注意的问题

1. 幂等性保障 1.1 幂等性介绍 幂等性是数学和计算机科学中某些运算的性质,它们可以被多次应⽤,⽽不会改变初始应⽤的结果. 应⽤程序的幂等性介绍 在应⽤程序中,幂等性就是指对⼀个系统进⾏重复调⽤(相同参数),不论请求多少次,这些请求对系统的影响都是相同的效果. ⽐如数据库…...

算法日记8:StarryCoding60(单调栈)

一、题目 二、解题思路&#xff1a; 题意为让我们找到每个元素的左边第一个比它小的元素&#xff0c;若不存在则输出-1 2.1法一&#xff1a;暴力&#xff08;0n2&#xff09; 首先&#xff0c;我们可以想到最朴素的算法&#xff1a;直接暴力两层for达成目标核心代码如下&…...

大象机器人发布首款穿戴式数据采集器myController S570,助力具身智能数据收集!

myController S570 具有较高的数据采集速度和远程控制能力&#xff0c;大大简化了人形机器人的编程。 myController S570 是一款可移动的轻量级外骨骼&#xff0c;具有 14 个关节、2 个操纵杆和 2 个按钮&#xff0c;它提供高数据采集速度&#xff0c;出色的兼容性&#xff0c…...

【银河麒麟高级服务器操作系统】业务访问慢网卡丢包现象分析及处理过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;product.kylinos.cn 开发者专区&#xff1a;developer.kylinos.cn 文档中心&#xff1a;document.kylinos.cn 交流论坛&#xff1a;forum.kylinos.cn 服务器环境以及配置 【内核版本…...

C语言之饭店外卖信息管理系统

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 C语言之饭店外卖信息管理系统 目录 设计题目设计目的设计任务描述设计要求输入和输出要求验…...

记一次 .NET某数字化协同管理系统 内存暴涨分析

一&#xff1a;背景 1. 讲故事 高级调试训练营里的一位朋友找到我&#xff0c;说他们跑在linux上的.NET程序出现了内存泄露的情况&#xff0c;上windbg观察发现内存都是IMAGE给吃掉了&#xff0c;那些image都标记了 doublemapper__deleted_ 字样&#xff0c;问我为啥会这样&a…...

部门管理查询部门,nginx反向代理,前端如何访问到后端Tomcat 注解@RequestParam

接口开发 增删改通常是不用返回data数据&#xff0c;返回null 列表查询-结果封装&#xff0c;时间 前后端联调测试 nginx反向代理&#xff0c;前端如何访问到后端Tomcat服务器 删除部门...

JS通过ASCII码值实现随机字符串的生成(可指定长度以及解决首位不出现数值)

在之前写过一篇“JS实现随机生成字符串&#xff08;可指定长度&#xff09;”&#xff0c;当时写的过于简单和传统&#xff0c;比较粗放。此次针对此问题&#xff0c;对随机生成字符串的功能进行优化处理&#xff0c;对随机取到的字符都通过程序自动来完成。 在写之前&#xff…...

速通Docker === 快速部署Redis主从集群

目录 镜像仓库介绍 持久化你的数据库 连接到其他容器 创建自定义网络 部署主节点 部署从节点 验证部署 总结 在现代应用架构中&#xff0c;Redis作为一个高性能的内存数据库&#xff0c;被广泛应用于缓存、会话存储、实时分析等多个领域。为了提高Redis的可用性和数据的…...

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(一)

Understanding Diffusion Models: A Unified Perspective&#xff08;一&#xff09; 文章概括引言&#xff1a;生成模型背景&#xff1a;ELBO、VAE 和分层 VAE证据下界&#xff08;Evidence Lower Bound&#xff09;变分自编码器 &#xff08;Variational Autoencoders&#x…...

stm32使用MDK5.35时遇到*** TOOLS.INI: TOOLCHAIN NOT INSTALLED

mdk5.35出现*** TOOLS.INI: TOOLCHAIN NOT INSTALLED的问题&#xff01;&#xff01;&#xff01;&#xff01; 以管理员身份重新打开MDK5.35.0.0&#xff0c;用keygen破解密码&#xff0c;但是一直提示我是没有破解成功。 解决办法&#xff1a; target 改成ARM...

在Ubuntu上安装RabbitMQ教程

1、安装erlang 因为rabbitmq是基于erlang开发的&#xff0c;所以要安装rabbitmq&#xff0c;首先需要安装erlang运行环境 apt-get install erlang执行命令查是否安装成功&#xff1a;erl&#xff0c;疯狂 Ctrlc 就能退出命令行 2、安装rabbitmq 1、查看erlang与rabbitmq版本…...

【算法】集合List和队列

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 零&#xff1a;集合&#xff0c;队列的用法 一&#xff1a;字母异位词分组 二&#xff1a;二叉树的锯…...

uniapps使用HTML5的io模块拷贝文件目录

最近在集成sqlite到uniapp的过程中&#xff0c;因为要将sqlite数据库预加载&#xff0c;所以需要使用HTML5的plus.io模块。使用过程中遇到了许多问题&#xff0c;比如文件路径总是解析不到等。尤其是应用私有文档目录’_doc’。 根据官方文档&#xff1a; 为了安全管理应用的…...

css‘s hover VS mobile

.animation {animation: 30s move infinite linear;/* &:hover {animation-play-state: paused;*/ }原本写的好好的&#xff0c;测试说&#xff1a;“移动端点击滚动条&#xff0c;跳转到其他页面后&#xff0c;返回当前页面&#xff0c;滚动条不滚动&#xff1b;可以优化位…...

工业制造离不开的BOM

在制造业的浩瀚星空中&#xff0c;物料清单&#xff08;BOM&#xff09;犹如“北极星”&#xff0c;牢牢指引着产品从设计蓝图迈向实物诞生的全过程。 BOM的分类 按照设计制造的不同阶段&#xff0c;将BOM划分为设计BOM、工艺BOM、制造BOM三种类型。 设计BOM Engineering BO…...

HTML中的`<!DOCTYPE html>`是什么意思?

诸神缄默不语-个人CSDN博文目录 在学习HTML时&#xff0c;我们经常会看到HTML文档的开头出现<!DOCTYPE html>&#xff0c;它是HTML文件的第一行。很多初学者可能会疑惑&#xff0c;为什么需要这行代码&#xff1f;它到底有什么作用呢&#xff1f;在这篇文章中&#xff0…...

C语言之斗地主游戏

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 ​ C语言之斗地主游戏 目录 程序概述程序设计 Card类CardGroup类Player类LastCards类Land…...

【玩转全栈】----Django制作部门管理页面

目录 大致效果 BootStrap BootStrap简介 BootStrap配置 BootStrap使用 基本配置 部分代码解释及注意&#xff1a; 用户编辑&#xff1a; 新添数据&#xff1a; 删除数据&#xff1a; 大致效果 我先给个大致效果&#xff0c;基本融合了Django、Bootstrap、css、html等等。 基于D…...