flutter-web中使用js工具类
文章目录
- 为什么要调用js
- 1. flutter-web
- 1. 引入js web/index.html
- 2. 创建工具js web/CryptoEnc.js
- 3. 创建对应的lib/js/js_interop.dart
- 4. 由于引入的js是针对web平台的,所以引入需要做引入处理
- 5. 使用
- 2. Android
- 1. 引入依赖
- 2. index.html
- 3. dart
- 引用
为什么要调用js
JavaScript拥有庞大且成熟的工具生态系统
1. flutter-web
1. 引入js web/index.html
<!-- Add the required JS libraries --><script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js" integrity="sha512-a+SUDuwNzXDvz4XrIcXHuCf089/iJAoN4lmrXJg18XnduKK6YlDHNRalv4yd1N40OKI80tFidF+rqTFKGPoWFQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/md5.min.js" integrity="sha512-ENWhXy+lET8kWcArT6ijA6HpVEALRmvzYBayGL6oFWl96exmq8Fjgxe2K6TAblHLP75Sa/a1YjHpIZRt+9hGOQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><!-- Register the js file where the logic is written --><script src="CryptoEnc.js" type="application/javascript"></script>
2. 创建工具js web/CryptoEnc.js
function CryptoEnc() {}CryptoEnc.prototype.encrypt = function(toEncObj){var toEnc = toEncObj.value;var encrypted = CryptoJS.MD5(toEnc);return encrypted;
}CryptoEnc.prototype.testFunc = function(toEncObj2){var toEnc = toEncObj2.value;return "========bbbbtestFunc"+toEnc;
}
3. 创建对应的lib/js/js_interop.dart
// #1
()
library js_interop;// The above two lines are required
import 'package:js/js.dart';// #2
()
class CryptoEnc {external CryptoEnc();external String encrypt(ToEncrypt toEncrypt);external String testFunc(ToEncrypt2 toEncrypt2);
}// #3
()
class ToEncrypt {external String get value;external factory ToEncrypt({String value});
}
()
class ToEncrypt2 {external String get value;external factory ToEncrypt2({String value});
}
4. 由于引入的js是针对web平台的,所以引入需要做引入处理
///encrypt.dart
class ToEncrypt {final String value;ToEncrypt({required this.value,});
}class ToEncrypt2 {final String value;ToEncrypt2({required this.value,});
}class CryptoEnc {CryptoEnc();String encrypt(ToEncrypt toEncrypt) {// We are not implementing any encryption for mobile for now.// This is just for demonstration.throw UnimplementedError();}String testFunc(ToEncrypt2 toEncrypt) {// We are not implementing any encryption for mobile for now.// This is just for demonstration.throw UnimplementedError();}
}///export_encrypt.dart
export 'encrypt.dart' if (dart.library.js) 'js_interop.dart';
5. 使用
var encVal = CryptoEnc().encrypt(ToEncrypt(value: "aaaaaa",),);var encVal2 = CryptoEnc().testFunc(ToEncrypt2(value: "cccc",));print(encVal);print("testFunc=$encVal2");
2. Android
1. 引入依赖
webview_flutter: ^4.4.2
2. index.html
<!DOCTYPE html>
<html>
<head><title>Test js dart</title></head>
<body>
<script>function inputClick (url) {console.log('inputClick=>'+url);}function playUrl(url) {console.log('playUrl=>'+url);}function startPlay() {console.log('startPlay');}function postMsg() {console.log('postMsg');//向dart发送消息Print.postMessage('postMsg');}</script>
</body>
</html>
3. dart
import 'package:flutter/material.dart';
import 'package:tvboxstudy/log_extensions.dart';
import 'package:webview_flutter/webview_flutter.dart';class LocalHtmlWebView extends StatefulWidget {const LocalHtmlWebView({super.key});LocalHtmlWebViewState createState() => LocalHtmlWebViewState();
}class LocalHtmlWebViewState extends State<LocalHtmlWebView> {late String localHtmlContents;late WebViewController controller;ValueNotifier<bool> isShowLoading = ValueNotifier(true);void initState() {super.initState();initController();loadLocalHtml();_registerJavascriptChannel();}void runJS(int type) {if (type == 1) {controller.runJavaScript('inputClick();',);} else if (type == 2) {controller.runJavaScript('startPlay();',);}else if (type == 3) {controller.runJavaScript('postMsg();',);} else if (type == 4) {controller.runJavaScript("playUrl('https://media.w3.org/2010/05/sintel/trailer.mp4');",);}}void _registerJavascriptChannel() {controller.addJavaScriptChannel('Print',onMessageReceived: (JavaScriptMessage message) {//收到消息做相应的处理print("onMessageReceived=>${message.message}");},);}void initController() {controller = WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted)..setBackgroundColor(Colors.transparent)..setJavaScriptMode(JavaScriptMode.unrestricted)..setNavigationDelegate(NavigationDelegate(onProgress: (int progress) {"progress=$progress".log();if (progress == 100) {isShowLoading.value = false;}},onPageStarted: (String url) {},onPageFinished: (String url) {controller.runJavaScriptReturningResult('document.body.scrollHeight').then((value) {"scrollHeight=>$value".log();});},onWebResourceError: (WebResourceError error) {},onNavigationRequest: (NavigationRequest request) {if (request.url.startsWith('https://www.youtube.com/')) {return NavigationDecision.prevent;}return NavigationDecision.navigate;},),);}void loadLocalHtml() async {controller.loadFlutterAsset('assets/www/player/index2.html');}Widget build(BuildContext context) {return Scaffold(body: Column(children: [Row(children: [TextButton(onPressed: (){runJS(1);}, child: Text("inputClick")),TextButton(onPressed: (){runJS(2);}, child: Text("startPlay")),TextButton(onPressed: (){runJS(3);}, child: Text("postMsg")),TextButton(onPressed: (){runJS(4);}, child: Text("playUrl")),],),Expanded(child: Stack(children: [WebViewWidget(controller: controller,),ValueListenableBuilder(valueListenable: isShowLoading,builder: (BuildContext context, bool value, Widget? child) {return isShowLoading.value? const Center(child: CircularProgressIndicator(color: Colors.white,)): const SizedBox.shrink();},)],),),],),);}
}
引用
Utilizing JS Library for Flutter Web
相关文章:
flutter-web中使用js工具类
文章目录 为什么要调用js1. flutter-web1. 引入js web/index.html2. 创建工具js web/CryptoEnc.js3. 创建对应的lib/js/js_interop.dart4. 由于引入的js是针对web平台的,所以引入需要做引入处理5. 使用 2. Android1. 引入依赖2. index.html3. dart引用 为什么要调用…...
@ResponseBody详解:用于响应体响应数据
RestFul风格或者是web阶段接触过的异步请求,都需要把数据转换成Json放入响应体中。 ResponseBody的作用其实是将java对象转为json格式的相应内容 使用 RequestMapping注解时,Spring会将返回值解析为视图路径,然后跳转路径返回对应的视图页面…...
【Python百练——第3练】矩形类及操作
💐作者:insist-- 💐个人主页:insist-- 的个人主页 理想主义的花,最终会盛开在浪漫主义的土壤里,我们的热情永远不会熄灭,在现实平凡中,我们终将上岸,阳光万里 ❤️欢迎点…...
【C语言学习疑难杂症】C语言中数组存储时为什么从低地址到高地址
在C语言中,数组的存储从低地址到高地址是有其历史原因的。这种设计主要是为了与计算机系统的内存组织方式相一致。 在计算机系统中,内存通常按照字节进行编址,地址从低到高递增。数组在内存中是连续存储的,因此数组的第一个元素&…...
Linux:查看端口占用的进程
命令 netstat -tunlp可以从图中看到,端口被那个进程占用,对应进程的pid是多少。...
医美店会员管理系统预约小程序作用是什么
医美在美业中占据着一定地位,爱美使然和经济独立、悦己消费下,不少女性会前往医美机构做脸部整容、嫩肤补水等服务,如美容院一样都是具备本地外地属性的,因此在如今互联网盛行下,商家需要借势线上破解难题及增强生意效…...
Linux 正则表达式
内容概述 1 文本编辑工具之神 VIM 1.1 vi 和 vim 简介 在 Linux 中我们经常编辑修改文本文件,即由 ASCII Unicode 或者其他编码的纯文字的文件。之前介绍过的 nano,实际工具中我们使用更为专业,功能强大的工具 文本编辑种类: vi…...
C语言面试之数组指针上篇
C语言数组是C语言中重要的数据结构之一,它用于存储一组相同类型的数据。数组在C语言中是以连续的内存空间来存储的,每个数组元素都是一个变量,占据一定的内存空间,数组元素之间是紧密相邻的。 一、数组的定义 在C语言中࿰…...
LinkWeChat,唯一以开源为核心的SCRM
LinkWeChat是国内首个基于企业微信的开源SCRM,在集成了企微强大的开放能力的基础上,进一步升级拓展灵活高效的客户运营能力及多元化精准营销能力,让客户与企业之间建立强链接,帮助企业提高客户运营效率,强化营销能力&a…...
Android textView 显示: STRING_TOO_LARGE
在Android中,字符串资源的长度限制是32KB,getString()方法返回的字符串资源的大小超过这个限制,就会抛出STRING_TOO_LARGE 这个错误。 我本地的临界值是:32.3 KB (33,090 字节) 小于等于33090时,能正常显示ÿ…...
用HeidiSQL在MySQL中创建新的数据库
用有权限的用户登录: 右键单击,选择: 输入要创建的数据库名称,然后点击“确定”: 刷新下,就看到新创建的数据库了: 在新创建的数据库中,就可以做其它操作了,例如…...
纯前端实现导入excel数据
准备工作 - 下载 xlsx npm install xlsx下面直接上代码👇 <template><div><input type"file" accept".xlsx, .xls" change"handleClick"></div> </template><script langts setup> import * a…...
Matlab下载许可证文件 教程(在账号有许可证的前提下)
文章目录 Part.I IntroductionPart.II 许可证文件过期解决方案Chap.I 使用 Internet 自动激活Chap.II 在不使用 Internet 的情况下手动激活 Part.I Introduction 本文主要介绍,在 Mathwork 账号有许可证的前提下,下载许可证的操作流程。 好久没有用 Mat…...
AI 绘画 | Stable Diffusion 电商模特
前言 上一篇文章讲到如何给人物更换背景和服装。今天主要讲电商模特,就是服装电商们的固定服装产品图片如何变成真人模特穿上的固定服装产品效果图。如果你掌握了 《AI 绘画 | Stable Diffusion 人物 换背景|换服装》,这篇文章对你来说,上手会更轻松。 教程 提取服装蒙版…...
vue面试题整理(1.0)
一、对MVC,MVP,MVVM的理解 三者都是项目的架构模式(不是类的设计模式),即:一个项目的结构,如何分层,不同层负责不同的职责。 1.MVC MVC的出现是用在后端(全栈时代&…...
PyQt基础_007_ 按钮类控件QCombox
import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import *class ComboxDemo(QWidget):def __init__(self, parentNone):super(ComboxDemo, self).__init__(parent)self.setWindowTitle("combox 例子") self.resize(300, 90) …...
Android Wifi的扫描机制
Android Wifi 的扫描场景分为下面四种情况: 1.亮屏情况下,在Wifi settings界面,固定扫描,扫描时间为10s。 2.亮屏情况下,在非Wifi settings界面,二进制指数退避扫描,退避:interval…...
类 —— 友元、常/静态成员函数
类 类的大小 和结构体大小求法一致。但需注意,普通空类也会占用 1 字节大小,因为普通空类可以实例化对象。 而 抽象空类占 4 字节(32 位机中),因为抽象空类中含有虚指针(含有虚函数的非抽象空类同理&am…...
单页面应用
单页面应用 1.什么是SPA 多页面应用:每个页面都是独立的html文件,页面切换是整体刷新,需要重新加载html、css、JS等文件,容易实现搜索引擎,数据通过url、cookie、localStore传递。 单页面应用:多个页面是…...
六、ZooKeeper Java API操作
目录 1、引入maven坐标 2、节点的操作 这里操作Zookeeper的JavaAPI使用的是一套zookeeper客户端框架 Curator ,解决了很多Zookeeper客户端非常底层的细节开发工作 。 Curator包含了几个包:...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
用 FFmpeg 实现 RTMP 推流直播
RTMP(Real-Time Messaging Protocol) 是直播行业中常用的传输协议。 一般来说,直播服务商会给你: ✅ 一个 RTMP 推流地址(你推视频上去) ✅ 一个 HLS 或 FLV 拉流地址(观众观看用)…...
以太网PHY布局布线指南
1. 简介 对于以太网布局布线遵循以下准则很重要,因为这将有助于减少信号发射,最大程度地减少噪声,确保器件作用,最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确,然…...
Unity-ECS详解
今天我们来了解Unity最先进的技术——ECS架构(EntityComponentSystem)。 Unity官方下有源码,我们下载源码后来学习。 ECS 与OOP(Object-Oriented Programming)对应,ECS是一种完全不同的编程范式与数据架构…...
