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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/149874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

尽快调整心态,切莫自讨苦吃

退休多年的老龄人的本“人民体验官”闲得无聊&#xff0c;怕被闲出更多病痛&#xff0c;更怕被闲死&#xff0c;所以天天上网坚持职业新闻人的老习惯——上网读新闻&#xff0c;并以一孔之见置评&#xff0c;旨在抛砖引玉。 11月8日&#xff0c;本“人民体验官 ”在推广人民日…

mysql主从搭建(docker)

一、主从概述 MySQL主从又叫Replication、AB复制。简单讲就是A与B两台机器做主从后&#xff0c;在A上写数据&#xff0c;另外一台B也会跟着写数据&#xff0c;实现数据实时同步。有这样几个关键点&#xff1a; 1&#xff09;MySQL主从是基于binlog&#xff0c;主上需开启binl…

debian10 开启rdp安装firefox,firefox 中文乱码

debian10 开启rdp安装firefox apt -y install tigervnc-standalone-server apt -y install xrdp tigervnc-standalone-server systemctl enable xrdpapt install firefox-esrmstsc连接 firefox-settings-general-fonts-advanced-Simplified Chinese

java Bigdecimal

一、BigDecimal概述 BigDecimal是Java在java.math包中提供的线程安全的API类&#xff0c;用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数&#xff0c;但在实际应用中&#xff0c;可能需要对更大或者更小的数进行运算和处理。一般情况下&am…

服务器探针-serverstatus

{alert type"info"} 之前给大家介绍过一个简单的服务器监控。uptime-kuma 今天给各位带来一个酷炫的多服务器探针和多服务器监控。ServerStatus {/alert} 作者的开源项目地址如下&#xff1a;https://github.com/cppla/ServerStatus 作者的项目体验地址如下 https://…

Ghidra逆向工具配置 MacOS 的启动台显示(Python)

写在前面 通过 ghidra 工具, 但是只能用命令行启动, 不太舒服, 写个脚本生成 MacOS 的 app 格式并导入启动台. 不算复杂, 主要是解析包的一些元信息还有裁剪软件图标(通过 MacOS 自带的 API) 脚本 #!/opt/homebrew/bin/python3import os import re import subprocess as sp…

离开大促的电商生意,应该怎么玩?

离开大促的电商生意&#xff0c;应该怎么玩&#xff1f; 2023-11-20 11:07DataStory 双11圆满收官&#xff0c;生意场上的角逐从未停止。 最近一周&#xff0c;各大平台纷纷晒出今年度战绩&#xff0c;天猫宣布全面增长&#xff0c;402个品牌成交破亿&#xff0c;3.8万个品牌…

Dockerfile自定义镜像以及案例分析

文章目录 一、Dockerfile自定义镜像1.1 镜像结构1.2 Dockerfile语法 二、构建Java项目三、基于java8构建java四、小结 一、Dockerfile自定义镜像 常见的镜像在DockerHub就能找到&#xff0c;但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像&#xff0c;就必须先了…

天梯赛 L2-047 锦标赛

原题链接&#xff1a; PTA | 程序设计类实验辅助教学平台 题面&#xff1a; 有 2k 名选手将要参加一场锦标赛。锦标赛共有 k 轮&#xff0c;其中第 i 轮的比赛共有 2k−i 场&#xff0c;每场比赛恰有两名选手参加并从中产生一名胜者。每场比赛的安排如下&#xff1a; 对于第 1…

多对多的创建方式与Ajax

模型层补充 MTV与MVC模型 MTV 全称 Models Templates Views 模型模板视图 MVC 全称 Models Views Controller 模型视图控制MTV: Django号称是MTV模型 MVC: 其实django本质也是MVC 拓展: vue框架:MVVM模型choices参数(数据库字段设计常见) choices使用 class User(models.Mod…

ansible-playbook剧本实现wordpress上线

准备环境&#xff1a; 1.需要三台服务器&#xff1a;主机服务器&#xff08;(10.36.192.129&#xff09;、db服务器(10.36.192.131)&#xff0c;web服务器(10.36.192.130)&#xff0c;剧本都是写在主机服务器上。 2.主机服务器需要做ansible解析 vim /etc/ansible/hosts[web…

CICD 持续集成与持续交付——jenkins

部署 软件下载&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/ [rootcicd2 ~]# rpm -ivh jdk-11.0.15_linux-x64_bin.rpm[rootcicd2 ~]# yum install -y fontconfig[rootcicd2 ~]# rpm -ivh jenkins-2.432-1.1.noarch.rpm启动服务 [rootcicd2 ~]# systemctl…

【JVM】Java虚拟机

本文主要介绍了JVM的内存区域划分,类加载机制以及垃圾回收机制. 其实JVM的初心,就是让java程序员不需要去了解JVM的细节,它把很多工作内部封装好了.但是学习JVM的内部原理有利于我们深入理解学习Java. 1.JVM的内存区域划分 JVM其实是一个java进程 ; 每个java进程,就是一个jvm…

MVSNet论文笔记

MVSNet论文笔记 摘要1 引言2 相关基础2.1 多视图立体视觉重建&#xff08;MVS Reconstruction&#xff09;2.2 基于学习的立体视觉&#xff08;Learned Stereo&#xff09;2.3 基于学习的多视图的立体视觉&#xff08;Learned MVS&#xff09; 3 MVSNet3.1 网络架构3.2 提取图片…

ModStartCMS v7.6.0 CMS备份恢复优化,主题开发文档更新

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

SAP ABAP结构与内表的创建

一、定义一个结构体 DATA:BEGIN OF LS_MATNR,MATNR TYPE MATNR,MAKTX TYPE MAKTX, END OF LS_MATNR. 二、定义一个包含表头的内表 DATA:BEGIN OF LT_MAT OCCURS 0,MATNR TYPE MATNR,MAKTX TYPE MAKTX, END OF LT_MAT. 三、参考数据结构来定义内表 DATA:LT_MAT LIKE TABLE…

OpenAI Assistants-API简明教程

OpenAI在11月6号的开发者大会上&#xff0c;除了公布了gpt4-v、gpt-4-turbo等新模型外&#xff0c;还有一个assistants-api&#xff0c;基于assistants-api开发者可以构建自己的AI助手&#xff0c;目前assistants-api有三类的工具可以用。首先就是之前大火的代码解释器(Code In…

苍穹外卖--菜品分页查询

设计DTO类 Data public class DishPageQueryDTO implements Serializable {private int page;private int pageSize;private String name;private Integer categoryId; //分类idprivate Integer status; //状态 0表示禁用 1表示启用}设计VO类 Data Builder NoArgsConstructor…

奇富科技发布鸿蒙元服务1.0版本,打造鸿蒙生态金融科技全新体验

近日&#xff0c;奇富科技率先发布鸿蒙元服务1.0版本&#xff0c;成为首家融入鸿蒙生态的金融科技公司&#xff0c;为用户带来前所未有的数字生活体验。此次与华为终端云的全面合作&#xff0c;是两大行业领军者的深度融合&#xff0c;不仅实现技术的交融&#xff0c;更彰显两大…

蓝桥杯 map

map 代码示例 #include<iostream> #include<map> using namespace std; int main(){//创建并初始化mapmap<int,string> myMap{{1,"Apple"},{2,"Banana"},{3,"Orange"}} ;//插入元素myMap.insert(make_pair(4,"Grapes&qu…