flutter 封装webview和使用本地网页

最先看到flutter_webview_plugin 用法特别简单

flutter_webview_plugin | Flutter PackagePlugin that allow Flutter to communicate with a native Webview.icon-default.png?t=N7T8https://pub-web.flutter-io.cn/packages/flutter_webview_plugin缺点: 没有实现js sdk的功能 没有办法 使用JavaScriptChannel 的功能

后面使用webview_flutter

webview_flutter | Flutter packageA Flutter plugin that provides a WebView widget on Android and iOS.icon-default.png?t=N7T8https://pub-web.flutter-io.cn/packages/webview_flutter组件

import 'dart:convert';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class AppWebView extends StatefulWidget {
  final String url;
  final Function(dynamic)? onMessageReceived;
  const AppWebView({
    super.key,
    required this.url,
    this.onMessageReceived,
  });

  @override
  State<AppWebView> createState() => _AppWebViewState();
}

class _AppWebViewState extends State<AppWebView> {
  late final WebViewController controller;

  int progress = 0;

  @override
  void initState() {
    super.initState();
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..addJavaScriptChannel("lh", onMessageReceived: onMessageReceived)
      ..enableZoom(true)
      ..setBackgroundColor(const Color(0x00000000))
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            // Update loading bar.
            this.progress = progress;
            setState(() {});
          },
          onPageStarted: (String url) {},
          onPageFinished: (String url) {},
          onWebResourceError: (WebResourceError error) {},
          onNavigationRequest: (NavigationRequest request) {
            if (request.url.startsWith('https://www.youtube.com/')) {
              return NavigationDecision.prevent;
            }
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse(widget.url));
  }

  // 接受h5发送来的数据
  onMessageReceived(message) async {
    widget.onMessageReceived?.call(message);
    //接收H5发过来的数据
    String sendMesStr = message.message;
    print("onMessageReceived sendMesStr:${sendMesStr}");
    Map<String, dynamic> msg = json.decode(sendMesStr);

    String method = msg["method"] ?? "";
    // Map<String, dynamic> data = msg["data"] ?? {};
    if (method.isNotEmpty) {
      switch (method) {
        case "back":
          controller.goBack();
          break;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
      return Scaffold(
        // appBar: AppBar(title: const Text('Flutter Simple Example')),
        body: Stack(children: [
          WebViewWidget(controller: controller),
          if (progress != 100)
            const Center(
              child: CupertinoActivityIndicator(),
            )
        ]),
      );
    } else {
      return const Center(
        child: Text('WebView control is not supported on this platform yet.'),
      );
    }
  }
}

使用

Get.to(() => AppWebView(
      url: 'http://localhost',
      onMessageReceived: onMessageReceived,
));

注意:需要重启项目才会生效

 

加载本地网页

String html =

    await rootBundle.loadString('assets/index.html');

String localHtmlFilePath = Uri.dataFromString(

  html,

  mimeType: 'text/html',

  encoding: Encoding.getByName('utf-8'),

).toString();

pubspec.yaml

  assets:

    - assets/index.html

使用

AppWebView(

  url: localHtmlFilePath,

   onMessageReceived: onMessageReceived,

)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣简单递归:左叶子之和

思路&#xff1a;重点在于每层都记录val的值以减少递归调用次数 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int sumOfLeftLeaves(struct TreeNode* root){ if(rootNULL) {re…

Mycat核心教程--ZooKeeper集群搭建【三】

Mycat核心教程--ZooKeeper集群搭建 八、 ZooKeeper集群搭建8.1.ZooKeeper简介8.2.数据复制的好处8.3.Zookeeper设计目的8.4.zookeeper集群包括3种角色8.4.1.Leader角色8.4.2.Follower 角色8.4.3.Observer 角色 8.5.zookeeper集群工作流程8.6.zookeeper集群节点数量为奇数&#…

高性能Server的基石:reactor反应堆模式

业务开发同学只关心业务处理流程。但是我们开发的程序都是运行服务端server上&#xff0c;服务端server接收到IO请求后&#xff0c;是如何处理请求并最终进入业务流程的呢&#xff1f;这里不得不提到reactor反应堆模型。reactor反应堆模型来源于大师Doug Lea在 《Sacalable io …

图形判断类型

笔画数 笔画数这一考点。在国考、省考以及事业单位、三支一扶等各种公务员考试当中&#xff0c;都作为一个重要考点的存在。但很多同学仍然对于这部分知识点不清晰&#xff0c;比如不知道如何数奇点&#xff0c;数不清奇点&#xff0c;或无法快速识别这类题型&#xff0c;以致…

抖音橱窗怎么关闭?

路径&#xff1a;【抖音APP-我-电商带货-全部工具-账号管理-权限与账户-关闭电商权限】关闭橱窗带货权限。 0保、原0粉达人关闭电商权限后&#xff0c;后续均需要满足页面提示要求才可以进行电商权限的开通&#xff0c;建议慎重操作。

从新手到专家:AutoCAD 完全指南

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 引言 AutoCAD是一款广泛用于工程设计和绘图的…

终于支持中文,开源手绘风格画板工具 Revezone 推荐!

Excalidraw 是一款老牌的手绘风格画板工具&#xff0c;颜值高&#xff0c;操作简单&#xff0c;GitHub 上拥有 69k 的 Star &#x1f449; https://excalidraw.com/ 可惜的是&#xff0c;Excalidraw 只有网页版&#xff0c;也不支持中文字体&#xff1a; 最近发现了国内开发者…

【k8s 高级调度--污点和容忍】

1、调度概念 在 Kubernetes 中&#xff0c;调度&#xff08;scheduling&#xff09;指的是确保 Pod 匹配到合适的节点&#xff0c; 以便 kubelet 能够运行它们。 抢占&#xff08;Preemption&#xff09;指的是终止低优先级的 Pod 以便高优先级的 Pod 可以调度运行的过程。 驱逐…

Time Travel

题目链接 解题思路 由于所有边集中的边加起来的总和至多为&#xff0c;无向图即&#xff0c;可以存下所以直接对所有边集中的边进行建边&#xff0c;同时对于每条边&#xff0c;记录其所在边集号对于每个边集&#xff0c;由大到小维护其能通过的时间点然后从1号跑最短路到当前…

笔记整理(安全)

第八天 内容安全 攻击可能是一个点&#xff0c;但是防御需要全方面进行 IAE 引擎 DFI和DPI技术 深度检测技术 DPI 深度包检测技术 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对数据包的内容进行识别&#xff08;应用…

python学习笔记-内置异常

概述 Python 中的异常&#xff08;Exception&#xff09;是指在程序执行过程中遇到的错误或异常情况。当程序出现异常时&#xff0c;解释器会停止当前代码的执行&#xff0c;并试图找到匹配的异常处理器来处理异常。如果没有找到合适的异常处理器&#xff0c;程序就会终止并打…

anaconda指定目录创建环境无效/环境无法创建到指定位置

已经设置目录到D盘 创建环境时还是分配到C盘 可能是指定位置没有开启读写权限&#xff0c;如我在这里安装到了anaconda文件夹&#xff0c;则打开该文件夹的属性->安全->编辑 allusers下的权限全都打勾

笔记:GO1.19 带来的优化(重新编译juicefs)

## 背景 go编写的应用程序&#xff08;juicefs&#xff09;在k8s&#xff08;docker&#xff09;中运行&#xff0c;时不时出现 OOM Killed。 ## 分析 发现某些应用使用juicefs会导致内存使用飙升&#xff1b; k8s的pod给的内存资源&#xff1a;request 2G&#xff0c;limit…

雾锁王国服务器要开服务器吗?

雾锁王国要开服务器吗&#xff1f;可以使用官方服务器&#xff0c;也可以自己搭建多人联机服务器&#xff0c;更稳定不卡&#xff0c;畅玩开黑。阿腾云分享atengyun.com给大家目前阿里云和腾讯云均提供雾锁王国服务器和一键搭建程序&#xff0c;成本26元即可搭建一台自己的雾锁…

回归预测 | Matlab实现OOA-HKELM鱼鹰算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现OOA-HKELM鱼鹰算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现OOA-HKELM鱼鹰算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现OOA-HKELM鱼鹰算法优化混合核极限学习机多变量…

LeetCode 2673.使二叉树所有路径值相等的最小代价:自顶向下的DFS 或 自底向上的递推

【LetMeFly】2673.使二叉树所有路径值相等的最小代价&#xff1a;自顶向下的DFS 或 自底向上的递推 力扣题目链接&#xff1a;https://leetcode.cn/problems/make-costs-of-paths-equal-in-a-binary-tree/ 给你一个整数 n 表示一棵 满二叉树 里面节点的数目&#xff0c;节点编…

【查漏补缺你的Vue基础】Vue数据监听深度解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

嵌入式学习第二十二天!(继续学习线程)

线程相关函数接口&#xff1a; 1. 线程分离属性&#xff1a; 线程结束后&#xff0c;自动回收线程空间 1. pthread_attr_init&#xff1a; int pthread_attr_init(pthread_attr_t *attr); 功能&#xff1a;线程属性初始化 2. pthread_attr_destroy&#xff1a; int pthread_…

居然才发现!字节跳动旗下国产AI绘画工具Dreamina,这么好用居然还免费!(强烈推荐)

昨天看到群里说&#xff0c;剪映旗下类似 Sora 的 AI 视频生成工具 Dreamina 开放内测申请了&#xff0c;于是申请了下&#xff0c;顺道发现 Dreamina 还是一个宝藏的 AI 绘画工具。 Dreamina 是剪映旗下的一个 AI 创作平台&#xff0c;目前支持「图片生成」功能&#xff0c;也…

MWC 2024丨生成式AIGC成为最大亮点—美格智能携手阿加犀推出多感知融合VSLAM解决方案

2024世界移动通信大会盛况空前&#xff0c;AI成为最大亮点。2月28日&#xff0c;美格智能携手阿加犀&#xff0c;将算力模组的硬件优势与AI优化部署技术相结合&#xff0c;在MWC展会现场展示了基于高算力AI模组的多感知融合VSLAM解决方案。这一创新性方案可应用于智能机器人与低…