Flutter在web项目中使用iframe
需要把原来的app项目移植到web上面,在app中使用的是flutter_inappwebview这个库,推荐使用这个库,因为修复了一部分webview_flutter中存在的问题
在web项目中flutter_inappwebview这个库不支持,所以需要自己封装一个web项目中的webview也就是使用iframe
废话少说上代码
import 'dart:html';
import 'dart:js' as js;import 'dart:ui_web';import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:myapp/app/services/screen_adapter.dart';Widget buildWebViewWidget(String url,{Function(int id)? onPlatformViewCreated}) {/// 给js调用的函数void back(){Get.back();}var platformViewRegistry = PlatformViewRegistry();//注册platformViewRegistry.registerViewFactory('iframe-webview', (_) {DivElement _mainDiv = DivElement()..style.width = '100%'..style.height = '100%'..style.position = 'relative';IFrameElement _iFameElement = IFrameElement()..style.height = '100%'..style.width = '100%'..src = url..style.border = 'none';ScriptElement scriptElement = ScriptElement();var script = """// 对话框jswindow.confirm = function(message, yesCallback, noCallback){var message = message;var choose = function(tag){return document.querySelector(tag);}choose('.dialog-message').innerHtml = message;choose(".wrap-dialog").className = "wrap-dialog";choose("#dialog").οnclick= function(e){if(e.target.className=="dialog-btn"){choose(".wrap-dialog").className = "wrap-dialog dialog-hide";yesCallback();}else if (e.target.className=="dialog-btn dialog-ml50"){choose(".wrap-dialog").className = "wrap-dialog dialog-hide";noCallback();}};}// 返回按钮功能var drag = document.getElementById("floatBtn");var gapWidth = ${ScreenAdapter.width(5)}var itemWidth = ${ScreenAdapter.width(80)}var itemHeight = ${ScreenAdapter.width(80)}var clientWidth = document.documentElement.clientWidthvar clientHeight = document.documentElement.clientHeightvar newLeft = 0var newTop = 0drag.addEventListener('click',function(e){//e.stopPropagation();var r = confirm('确定返回首页吗?', function(){window.back();}, function(){})})drag.addEventListener('touchstart', function(e){// e.preventDefault();//e.stopPropagation();drag.style.transition = 'none';})drag.addEventListener('touchmove', function(e){// e.preventDefault();// e.stopPropagation();if (e.targetTouches.length === 1) {let touch = e.targetTouches[0]newLeft = touch.clientX - itemWidth / 2;newTop = touch.clientY - itemHeight / 2;if(newLeft < 0){newLeft = 0} if(newLeft > clientWidth - itemWidth - gapWidth){newLeft > clientWidth - itemWidth - gapWidth}if(newTop < 0){newTop=0;}if(newTop > clientHeight - itemHeight - gapWidth){newTop = clientHeight - itemHeight - gapWidth}drag.style.left = newLeft + 'px'drag.style.top = newTop + 'px'}})drag.addEventListener('touchend', function (e) {// e.preventDefault()//e.stopPropagation();drag.style.transition = 'all 0.3s'if (newLeft > clientWidth / 2) {newLeft = clientWidth - itemWidth - gapWidth} else {newLeft = gapWidth}drag.style.left = newLeft + 'px'}) """;scriptElement.innerHtml = script;/// 返回按钮divDivElement _div = DivElement()..id = 'floatBtn'..draggable = true..style.width = '${ScreenAdapter.width(80)}px'..style.height = '${ScreenAdapter.width(80)}px'// ..style.backgroundColor = 'red'..style.backgroundImage = 'url(assets/assets/images/fanhui.png)'..style.backgroundSize = 'cover'..style.position = 'absolute'..style.left = '${ScreenAdapter.width(5)}px'..style.top = '0'..style.transition = 'all 0.3s'..style.zIndex = '9999';// 对话框样式StyleElement _style = StyleElement();_style.innerHtml = """html,body {margin: 0;padding: 0;font-family: "Microsoft YaHei";}.wrap-dialog {position: fixed;top: 0;left: 0;width: 100%;height: 100%;font-size: 16px;text-align: center;background-color: rgba(0, 0, 0, .4);z-index: 10000;display: flex;justify-content: center;align-items: center;}.dialog {position: relative;margin: 10% auto;width: 300px;background-color: #FFFFFF;}.dialog .dialog-header {height: 20px;padding: 10px;background-color: #22b9ff;}.dialog .dialog-body {height: 30px;padding: 20px;}.dialog .dialog-footer {padding: 8px;background-color: #f5f5f5;}.dialog-btn {width: 70px;padding: 2px;cursor: pointer;}.dialog-hide {display: none;}.dialog-ml50 {margin-left: 50px;}""";_mainDiv.append(_style);// 提示信息框domDivElement _dialogDiv = DivElement();_dialogDiv.innerHtml = """<div class="wrap-dialog dialog-hide" ><div class="dialog" id="dialog"><div class="dialog-header"><span class="dialog-title">提示</span></div><div class="dialog-body"><span class="dialog-message">确定要返回首页吗?</span></div><div class="dialog-footer"><input type="button" class="dialog-btn" id="dialog-confirm" value="确认" /><input type="button" class="dialog-btn dialog-ml50" id="dialog-cancel" value="取消" /></div></div></div>""";_mainDiv.append(scriptElement);_mainDiv.append(_dialogDiv);_mainDiv.append(_div);_mainDiv.append(_iFameElement);return _mainDiv;});/// 注册返回函数js.context['back'] = back;return SizedBox(width: double.infinity,height: double.infinity,child: HtmlElementView(viewType: 'iframe-webview',onPlatformViewCreated: (int id) {onPlatformViewCreated?.call(id);},),);
}
使用方法
直接判断是否是web,GetPlatform.isWeb ,如果是则使用上面封装的,不是则调用其他平台的
if(GetPlatform.isWeb)buildWebViewWidgetPlatform(controller.url,onPlatformViewCreated: (id) {controller.isLoading.value = false;})
参考网址
https://juejin.cn/post/7294638699417042954
相关文章:
Flutter在web项目中使用iframe
需要把原来的app项目移植到web上面,在app中使用的是flutter_inappwebview这个库,推荐使用这个库,因为修复了一部分webview_flutter中存在的问题 在web项目中flutter_inappwebview这个库不支持,所以需要自己封装一个web项目中的we…...
阿里云高校计划学生和教师完成认证领取优惠权益
阿里云高校计划学生和教师均可参与,完成学生认证和教师验证后学生可以免费领取300元无门槛代金券和3折优惠折扣,适用于云服务器等全量公共云产品,订单原价金额封顶5000元/年,阿里云百科aliyunbaike.com分享阿里云高校计划入口及学…...
劲松HPV防治诊疗中心提醒:做完HPV检查后,需留意这些事项!
在接受HPV检查后,有一些注意事项需要您注意。首先,要遵循医生的建议,并按照医生的指示进行后续治疗和随访。 其次,检查后可能会有些不适感,这是正常的现象,不必过于担心。但是,如果不适感持续加…...
InfoNCE Loss公式及源码理解
InfoNCE Loss公式及源码理解–从交叉熵损失谈起 当谈论到信息论中的损失函数时,InfoNCE(Noise Contrastive Estimation)和交叉熵损失都是两个关键的概念。它们不仅在衡量概率分布之间的差异方面发挥着重要作用,而且在深度学习的自…...
经典双指针算法试题(二)
📘北尘_:个人主页 🌎个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 文章目录 一、有效三角形的个数1、题目讲解2、讲解算法原理3、代码实现 二、查找总价格为目标值的两个商…...
MySQL -- DQL
1、select查询列和列名: --查询所有员工信息(*通配符,默认查询所有的列) select * from emp;--查询员工的姓名 select ename from emp;--查询员工的薪资 select sal from emp;--查询员工的姓名和薪资 select ename , sal from emp; select ename sal fr…...
高防CDN:保障网络安全的未来之路
在当前数字化飞速发展的时代,网络安全问题日益成为企业和个人关注的焦点。高防CDN(Content Delivery Network,内容分发网络)作为一种专注于防御网络攻击的解决方案,尽管在技术上表现卓越,但其普及却面临一系…...
使用wxPython和PyMuPDF合并PDF文档并自动复制到剪贴板
导语:处理大量的PDF文档可能会变得复杂和耗时。但是,使用Python编程和一些强大的库,如wxPython和PyMuPDF,可以使这个任务变得简单而高效。本文将详细解释一个示例代码,展示如何使用这些库来创建一个可以选择文件夹中的…...
Redis篇---第十四篇
系列文章目录 文章目录 系列文章目录前言一、为什么Redis的操作是原子性的,怎么保证原子性的?二、了解Redis的事务吗?四、Redis 的数据类型及使用场景前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男…...
python之文件操作
文件的读取、修改、写入 知识点:不可以使用for循环生成变量,替代方式:将每次循环生成的数据添加到列表中,再对列表进行操作 例子:根据输入的环境名称操作hosts文件,注释掉其他环境 #env1 127.0.0.1 127.0.…...
android实时投屏软件QtScrcpy
QtScrcpy 可以通过 USB / 网络连接Android设备,并进行显示和控制。无需root权限。 同时支持 GNU/Linux ,Windows 和 MacOS 三大主流桌面平台。 QtScrcpy: Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制…...
LeetCode - 622. 设计循环队列(C语言,顺序存储结构,配图)
目录 编辑定义结构体: 1. MyCircularQueue(k): 构造器,设置队列长度为 k 2. Front: 从队首获取元素。如果队列为空,返回 -1 3. Rear: 获取队尾元素。如果队列为空,返回 -1 4. enQueue(value): 向循环队列插入一个元素。…...
在 Qt 框架中,有许多内置的信号可用于不同的类和对象\triggered
在 Qt 框架中,有许多内置的信号可用于不同的类和对象 以下是一些常见的内置信号的示例: clicked():按钮(QPushButton、QToolButton 等)被点击时触发的信号。 pressed() 和 released():按钮被按下和释放时…...
springBoot中starter
springBoot项目中引入starter 项目引入xxljob,仅需要导入对应的starter包,即可进行快速开发 <dependency><groupId>com.ydl</groupId><artifactId>xxl-job-spring-boot-starter</artifactId><version>0.0.1-SNAPS…...
Linux学习笔记-Ubuntu下使用Crontab设置定时任务
文章目录 一、概述二、基于crontab的设置2.1 基本命令说明2.2 使用-e指令编辑命令2.2.1 进入编辑模式2.2.2 指令信息格式2.2.4 开启日志1) 修改rsyslog配置文件2) 重启rsyslog3) 查看日志 2.2.3 设置后之后重启服务 三、示例3.1 每隔一分钟往文件中日期3.2 使用-l查看任务列表3…...
动态规划求数组中相邻两数的最小差值( 即相差的绝对值 ) java 实现
算法的核心是:计算当前数和前一个数的差值,用该差值和以前最小的连续数的差值作比较;如果当前的差值更小,则发现了更小的连续数的差值;如果当前的差值更大,则沿用以前的最小连续数差值作为新的最小连续数差值。 MinDif…...
webGL开发微信小游戏
WebGL 是一种用于在浏览器中渲染 2D 和 3D 图形的 JavaScript API。微信小游戏本质上是在微信环境中运行的基于 Web 技术的应用,因此你可以使用 WebGL 来开发小游戏。以下是基于 WebGL 开发微信小游戏的一般步骤,希望对大家有所帮助。北京木奇移动技术有…...
leetcode面试经典150题——29 三数之和
题目:盛最多水的容器 描述: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意…...
数据分析基础之《jupyter notebook工具》
一、安装库 1、linux库 yum install python3-devel 2、python库 pip3 install -U matplotlib pip3 install -U numpy pip3 install -U pandas pip3 install -U TA-Lib pip3 install -U tables pip3 install -U notebook 3、如果TA-Lib安装不上,先手动安装依赖库 …...
Android Studio Error “Unsupported class file major version 61“---异常信息记录
编译时异常信息 原因及解决办法 问题出在JAVA 17上,并且使用的Gradle JDK是:Android Studio java home版本17.0.1将其更改为:Android Studio默认JDK版本11.0.10 即可解决 操作步骤 1 2 3...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
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.…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
