FlutterBoost 实现Flutter页面内嵌iOS view
在使用Flutter混合开发中会遇到一些原生比Flutter优秀的控件,不想使用Flutter的控件,想在Flutter中使用原生控件。这时就会用到 Flutter页面中内嵌 原生view,这里简单介绍一个 内嵌 iOS 的view。
注:这里使用了 FlutterBoost。网上大部分都是代码执行不起来,本案例起码可以正常使用。
- 原生部分
这里开始在原生部分进行处理 - 自定义 view
FlutterIosTextLabel
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>NS_ASSUME_NONNULL_BEGIN@interface FlutterIosTextLabel : NSObject<FlutterPlatformView>@property (nonatomic, strong) UILabel *label;- (instancetype)initWithFrame:(CGRect)frameviewIdentifier:(int64_t)viewIdarguments:(id _Nullable)argsbinaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;@endNS_ASSUME_NONNULL_END
#import "FlutterIosTextLabel.h"@implementation FlutterIosTextLabel//在这里只是创建了一个UILabel
- (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {if (self = [super init]) {self.label = [UILabel new];self.label.backgroundColor = [UIColor yellowColor];self.label.textColor = [UIColor redColor];self.label.textAlignment = NSTextAlignmentCenter;self.label.numberOfLines = 0;NSDictionary *dict = (NSDictionary *)args;NSString *textValue = dict[@"content"];self.label.text = [NSString stringWithFormat:@"我是iOSView \n在显示:%@", textValue];}return self;
}- (nonnull UIView *)view {return self.label;
}@end
- 创建
FlutterIosTextLabelFactory
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>NS_ASSUME_NONNULL_BEGIN@interface FlutterIosTextLabelFactory : NSObject<FlutterPlatformViewFactory>- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;@endNS_ASSUME_NONNULL_END
#import "FlutterIosTextLabelFactory.h"
#import "FlutterIosTextLabel.h"@implementation FlutterIosTextLabelFactory
{NSObject<FlutterBinaryMessenger> *_messenger;
}- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {self = [super init];if (self) {_messenger = messenger;}return self;
}- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {return [[FlutterIosTextLabel alloc] initWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
}-(NSObject<FlutterMessageCodec> *)createArgsCodec{return [FlutterStandardMessageCodec sharedInstance];
}
- 创建
FlutterIosTextLabelPlugin
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>NS_ASSUME_NONNULL_BEGIN@interface FlutterIosTextLabelPlugin : NSObject<FlutterPlugin>
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar;
@endNS_ASSUME_NONNULL_END
#import "FlutterIosTextLabelPlugin.h"
#import "FlutterIosTextLabelFactory.h"@implementation FlutterIosTextLabelPlugin+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar {//注册插件//注册 FlutterIosTextLabelFactory//custom_platform_view 为flutter 调用此 textLabel 的标识[registrar registerViewFactory:[[FlutterIosTextLabelFactory alloc] initWithMessenger:registrar.messenger] withId:@"custom_platform_view"];
}
@end
到此原生已经集成完成一半,重点是接下来部分。
在 AppDelegate 中集成使用
修改AppDelegate.h:修改继承为FlutterAppDelegate,并删除window属性,因为FlutterAppDelegate中已经自带window属性
#import <UIKit/UIKit.h>
#import <Flutter/Flutter.h>@interface AppDelegate : FlutterAppDelegate
@end
在AppDelegate.m中引入相关头文件
#import "FlutterIosTextLabel.h"
#import "GeneratedPluginRegistrant.h"
#import "FlutterIosTextLabelPlugin.h"
在AppDelegate.m中注册插件,在引入 flutter_boost的情况下,需要等 flutter_boost初始化完成后,用FlutterEngine对插件进行初始化。
@interface AppDelegate ()@end@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {HYFlutterBoostDelegate* delegate = [[HYFlutterBoostDelegate alloc]init];self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];self.window.backgroundColor = [UIColor whiteColor];HYTabBarController *tab = [[HYTabBarController alloc]init];self.window.rootViewController = tab;[self.window makeKeyAndVisible];[FlutterBoost.instance setup:application delegate:delegate callback:^(FlutterEngine *engine) {NSLog(@"FlutterBoost 开始操作");// 使用 MethodChannel[HYFlutterNavChannel start];[HYFlutterCommonChannel start];// 初始化Flutter内嵌iOSView插件
// NSObject<FlutterPluginRegistrar> *registrar = [engine registrarForPlugin:@"custom_platform_view_plugin"];
// FlutterIosTextLabelFactory *factory = [[FlutterIosTextLabelFactory alloc] initWithMessenger:registrar.messenger];
// [registrar registerViewFactory:factory withId:@"custom_platform_view"];// 升级处理NSObject<FlutterPluginRegistrar> *registrar = [engine registrarForPlugin:@"custom_platform_view_plugin"];[FlutterIosTextLabelPlugin registerWithRegistrar:registrar];}];return YES;
}@end
到此原生集成完毕,接下来在 Flutter中进行集成
- Flutter 部分
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';class CMNativePage extends StatelessWidget {const CMNativePage({Key? key}) : super(key: key);Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("详情"),),body: const Center(child: IOSCompositionWidget(),),);}
}class IOSCompositionWidget extends StatelessWidget {const IOSCompositionWidget({super.key});Widget build(BuildContext context) {// This is used in the platform side to register the view.const String viewType = 'custom_platform_view';// Pass parameters to the platform side.final Map<String, dynamic> creationParams = {'content': 'Flutter传给原生iOSView的参数'};return UiKitView(viewType: viewType,creationParams: creationParams,creationParamsCodec: const StandardMessageCodec(),);}
}
注册路由
static const String nativaPage = '/nativaPage';
nativaPage: (settings, uniqued) {return MaterialPageRoute(settings: settings,builder: (_) {return const CMNativePage();});},
在Flutter地方使用
TextButton(child: const Text("加载原生控件"),onPressed: () {BoostNavigator.instance.push(HYRouter.nativaPage, arguments: {"home": "home页面传递数值"});// showBottomWidget(context, const CMNativePage());},),
到此Flutter中也完成集成。
如果想要某些弹出样式,自己再进行处理。这里只是简单的使用Flutter 内嵌 iOS原生view。
注意事项:
FlutterIosTextLabelFactory中的createArgsCodec方法一定不能遗漏,否则会导致传值不成功。类型也一定要和Dart部分的native.dart->IOSCompositionWidget->UiKitView->creationParamsCodec保持一致。否则会导致崩溃。- 使用官方文档中的写法是没有问题,但是本案例中使用了flutter_boost,再跟着官网集成就会出现问题。需要更
flutter_boost初始化完成,再对FlutterEngine对插件进行初始化。 - 其中
withId:xxx,xxx代表控件的ID,需要和Dart部分的IOSCompositionWidget中的viewType保持一致。命名为:custom_platform_view。 - 其中
registrarForPlugin:xxx,xxx代表插件的ID。命名为:custom_platform_view_plugin。
相关文章:
FlutterBoost 实现Flutter页面内嵌iOS view
在使用Flutter混合开发中会遇到一些原生比Flutter优秀的控件,不想使用Flutter的控件,想在Flutter中使用原生控件。这时就会用到 Flutter页面中内嵌 原生view,这里简单介绍一个 内嵌 iOS 的view。 注:这里使用了 FlutterBoost。网…...
走嵌入式还是纯软件?学长告诉你怎么选
最近有不少理工科的本科生问我,未来是走嵌入式还是纯软件好,究竟什么样的同学适合学习嵌入式呢?在这里我整合一下给他们的回答,根据自己的经验提供一些建议。 嵌入式领域也可以分为单片机方向、Linux方向和安卓方向。如果你的专业…...
【云计算原理及实战】初识云计算
该学习笔记取自《云计算原理及实战》一书,关于具体描述可以查阅原本书籍。 云计算被视为“革命性的计算模型”,因为它通过互联网自由流通使超级计算能力成为可能。 2006年8月,在圣何塞举办的SES(捜索引擎战略)大会上&a…...
Open3D (C++) 基于拟合高差的点云地面点提取
目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、原始点云2、提取结果四、相关链接系列文章(连载中。。。): Open3D (C++) 基于高程的点云地面点提取Open3D (C++) 基于拟合平面的点云地面点提取Open3D (C++) 基于拟合高差的点云地面点提取</...
认识Transformer:入门知识
视频链接: https://www.youtube.com/watch?vugWDIIOHtPA&listPLJV_el3uVTsOK_ZK5L0Iv_EQoL1JefRL4&index60 文章目录 Self-Attention layerMulti-head self-attentionPositional encodingSeq2Seq with AttentionTransformerUniversal Transformer Seq2Seq …...
《TCP IP网络编程》第二十四章
第 24 章 制作 HTTP 服务器端 24.1 HTTP 概要 本章将编写 HTTP(HyperText Transfer Protocol,超文本传输协议)服务器端,即 Web 服务器端。 理解 Web 服务器端: web服务器端就是要基于 HTTP 协议,将网页对…...
【AI】文心一言的使用
一、获得内测资格: 1、点击网页链接申请:https://yiyan.baidu.com/ 2、点击加入体验,等待通过 二、获得AI伙伴内测名额 1、收到短信通知,点击链接 网页Link:https://chat.baidu.com/page/launch.html?fa&sourc…...
CSAPP Lab2:Bomb Lab
说明 6关卡,每个关卡需要输入相应的内容,通过逆向工程来获取对应关卡的通过条件 准备工作 环境 需要用到gdb调试器 apt-get install gdb系统: Ubuntu 22.04 本实验会用到的gdb调试器的指令如下 r或者 run或者run filename 运行程序,run filename就…...
Java中使用流将两个集合根据某个字段进行过滤去重?
Java中使用流将两个集合根据某个字段进行过滤去重? 在Java中,您可以使用流(Stream)来过滤和去重两个集合。下面是一个示例代码,展示如何根据对象的某个字段进行过滤和去重操作: import java.util.ArrayList; import java.util.List; impor…...
自动驾驶HMI产品技术方案
版本变更 序号 日期 变更内容 编制人 审核人 文档版本 1 2 1....
Git判断本地是否最新
场景需求 需要判断是否有新内容更新,确定有更新之后执行pull操作,然后pull成功之后再将新内容进行复制到其他地方 pgit log -1 --prettyformat:"%H" HEAD -- . "origin/HEAD" rgit rev-parse origin/HEAD if [[ $p $r ]];thenecho "Is La…...
Spring 整合RabbitMQ,笔记整理
1.创建生产者工程 spring-rabbitmq-producer 2.pom.xml添加依赖 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.7.RELEASE</version></dep…...
Lua 语言笔记(一)
1. 变量命名规范 弱类型语言(动态类型语言),定义变量的时候,不需要类型修饰 而且,变量类型可以随时改变每行代码结束的时候,要不要分号都可以变量名 由数字,字母下划线组成,不能以数字开头,也不…...
【Redis】什么是缓存穿透,如何预防缓存穿透?
【Redis】什么是缓存穿透,如何预防缓存穿透? 缓存穿透是指查询一个一定不存在的数据,由于缓存中不存在,这时会去数据库查询查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,这…...
LeetCode128.最长连续序列
我这个方法有点投机取巧了,题目说时间复杂度最多O(n),而我调用了Arrays.sort()方法,他的时间复杂度是n*log(n),但是AC了,这样的话这道题还是非常简单的,创建一个Hashmap,以nums数组的元素作为ke…...
Datawhale Django入门组队学习Task02
Task02 首先启动虚拟环境(复习一下之前的) 先退出conda的, conda deactivate然后cd到我的venv下面 ,然后cd 到 scripts,再 activate (powershell里面) 创建admin管理员 首先cd到项目路径下&a…...
PCTA 认证考试高分通过经验分享
作者: msx-yzu 原文来源: https://tidb.net/blog/0b343c9f 序言 我在2023年8月10日,参加了 PingCAP 认证 TiDB 数据库专员 V6 考试 ,并以 90分 的成绩通过考试。 考试总分是100分,超过60分就算通过考试。试卷…...
[Python]pytorch与C交互
文章目录 C库ctypes基础数据类型参数与返回值类型数组指针结构体类型回调函数工具函数 示例 ctypes是Python的外部函数,提供了与C兼容的类型,并允许调用DLL库中的函数。 C库 要使函数能被Python调用,需要编译为动态库: # -fPIC…...
C语言,静态变量static基础及使用实列
static关键字有多种用途。以下是关于静态变量 (static) 的简要概述: 1.静态局部变量: - 在函数内部定义的静态变量。 - 生命周期:从程序开始执行到程序结束。 - 作用域:仅限于在其被定义的函数中。 - 每次调用该函数…...
2023.8.19-2023.8.XX 周报【人脸3D+虚拟服装方向基础调研-Cycle Diffusion\Diffusion-GAN\】更新中
学习目标 1. 这篇是做diffusion和gan结合的,可以参照一下看看能不能做cyclegan的形式,同时也可以调研一下有没有人follow这篇论文做了类似cyclegan的事情 Diffusion-GAN论文精读https://arxiv.org/abs/2206.02262 2. https://arxiv.org/abs/2212.06…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
背包问题双雄:01 背包与完全背包详解(Java 实现)
一、背包问题概述 背包问题是动态规划领域的经典问题,其核心在于如何在有限容量的背包中选择物品,使得总价值最大化。根据物品选择规则的不同,主要分为两类: 01 背包:每件物品最多选 1 次(选或不选&#…...
python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...
