从零开始开发纯血鸿蒙应用之网页浏览
从零开始开发纯血鸿蒙应用
- 〇、前言
- 一、优化菜单交互
- 1、BuilderFunction.ets
- 2、改造 PageTitleBar
- 二、网址打开
- 1、方式选择
- 1、使用浏览器打开
- 2、内部打开
- 2.1、声明权限
- 2.2、封装 WebViewPage
- 2.2.1、组件字段
- 2.2.2、aboutToAppear
- 2.2.3、onBackPress
- 2.2.4、标题栏
- 2.2.4、网页内容展示
- 2.3、实现效果
- 三、总结
〇、前言
一直以来,桌面应用也好,手机应用也罢,对于网址的访问,无非两种形式:用浏览器打开和自身内部打开,那么这两种方式,在鸿蒙应用开发框架中,又当如何实现呢?且看下文。
一、优化菜单交互
如果你没有跳过前面的几篇,那么应该知道,在文件内容编辑和查看界面的右上角菜单,我一直没有确定应该提供什么样的功能,现在,是时候替换其中一个了。
也同样是在前面的内容中,我已经利用 @BuilderParam 和 @Builder,将菜单从组件外传入,然而,这一组装饰器还有一种带参的使用方式,在进行改造之前,菜单的实现代码长成这样:


如果,我想要让“查看”这一菜单项的功能,为打开一个弹窗,仅是将 promptAction.showToast({message: "点击了查看"}) 换成 this.dialog.open(),不仅无法实现预期响应,反而还会带来应用奔溃的问题。
如果想要 this.dialog.oepn() 这种代码正常运行,就必须使用带参版的自定义构建函数,下面就跟着我的步骤进行改造。
1、BuilderFunction.ets
考虑到后续丰富 TxtEdit 功能时,可能会大量使用自定义构建函数,所以,不妨新建一个脚本文件,专门来存放这类代码,如此一来,相同的菜单实现内容,也可以很方便的进行多处使用。这个脚本,我本人是将其放在了lib_comps模块,如果屏幕前的你,有其他想法,尽管按照你的想法去按排。

大部分代码同之前的一样,区别就在于方法名变更,同时还增加了方法参数、一个类型为 MenuOption 的参数。$$ 是 ArkTS 语言提供的具有 双向绑定能力的运算符。
2、改造 PageTitleBar
相对应的,PageTitleBar 组件的实现代码也进行相应的变更:

而使用了 PageTitleBar 的相关页面,需要将具体的菜单功能逻辑,通过 PageTitleBar 的 viewOption 字段传入,例如下面:

二、网址打开
1、方式选择
既然打开网址有两种方式,那么就需要由用户自己选择对应的方式,所以,就需要一个对话框去询问用户:

这个对话框的实现效果如下:

1、使用浏览器打开
首先,看一下使用现成的系统浏览器打开网址,应当怎么样实现?
其实,原理还是调用第三方应用的那一套,也即用 common.UIAbilityContext.startAbility 的方式:

在拉起系统浏览器之前,先对用户输入的网址进行合法性校验,比如不能为空,以及限定为 http 协议。
2、内部打开
这种方式,想当然的,就需要封装一个专门的页面进行网页内容的展示,核心思想就是利用鸿蒙开发框架现成的 WebView API 和 Web 组件。
2.1、声明权限
打开线上网页,需要使用网络,所以,需要声明 ohos.permission.INTERNET 权限,同时,一些网页的正在运作需要定位权限,因此,可以一并在 Entry 模块的 module.json5 文件中,用 requestPermissions 标签,将所有权限声明好:

对于由系统授权的权限,可以只写权限名,而对于需要用户授予的权限,除了权限名,使用原因和使用方式都必须写明。
2.2、封装 WebViewPage
整体代码如下:

按照从上到下的顺序,逐个部分进行讲解。
2.2.1、组件字段
WebViewPage 一共声明定义了四个字段:
1)ctx:关联UI上下文的字段
2)root:定义页面根组件 Column 样式的字段
3)webController:获取控制Web组件的控制器实例的字段
4)url:保存拉起当前页面传入的网址的字段
2.2.2、aboutToAppear
在 WebViewPage 中,声明周期函数 aboutToAppear 需要做的事情有两件,一是将网址从路由参数中解析出来,二是向用户申请定位权限。

2.2.3、onBackPress
onBackPress 函数,不是声明周期函数,而是页面级的事件函数,对应返回事件,当用户使用返回手势和返回按钮时,就会调用该函数。WebViewPage 之所以不保持 onBackPress 的默认实现,是为了兼容 网页后退和app页面后退。
Web 组件,作为呈现网页内容的组件,具备了像浏览器那样记忆网页访问顺序的能力,也即内置了网页栈;当网页栈中不止一个网页,那么就可以进行网页后退,反之就不行;而确定当前 Web 组件能不能进行网页后退,可以利用 WebController 提供的 accessBackward 进行判断:

所以,onBackPress 就可以使用如下的代码去实现页面返回的兼容处理:

onBackPress 的返回值,是有特殊含义的;返回 true 时,表示返回事件由当前页面自行处理,返回 false 则表示由系统默认逻辑处理。
2.2.4、标题栏
由于 WebViewPage 需要在标题栏右侧,提供一个触发网页刷新的控件,所以,不适合直接用事先封装好的 PageTitleBar 组件,需要现场设计一个:

标题栏,理所应当要用行布局,并且是两端对齐、黑色背景。整个标题栏一共有三个控件,最左侧是返回控件,一样是兼容网页回退和app页面回退;中间部分是页面标题,固定显示内容”网页浏览“,并且当用户点击该控件时,会将网页内容滚回顶部位置;最右侧是刷新网页的控件,用户点击它就会触发网页刷新。
标题栏的三个控件中,除了返回控件外,剩下的两个,其交互实现都是基于 WebviewController 的。
2.2.4、网页内容展示
展示网页内容,可以用鸿蒙框架的内置组件 Web:

使用时,有几个组件属性必须设置好:

1)JavaScriptAccess 属性

现在的网页,大部分在实现时都会用到大量的 Javascript 代码,所以开启支持才能保证大部分网页可以被正常显示出来。
2)domStorageAccess 属性

不同于 JavaScriptAccess 属性的默认开启,domStorageAccess 属性是默认关闭的,然而,鉴于许多网页会用到 DOM Storage API,所以,设置为开启比较好。
3)onGeolocationShow
Web 组件有一个 geolocationAccess(geolocationAccess: boolean) 属性,设置是否开启获取地理位置权限,并且默认是开启的,然而,由于定位权限是用户授权的,因此,鸿蒙应用市场审核要求,规定使用Web组件且用到定位能力时,必须向用户弹窗申请定位权限,而这个申请弹窗,就可以放在 onGeolocationShow 中进行实现:

2.3、实现效果
最终,上述代码运作时的实现效果如下:

三、总结
本篇围绕如何在纯血鸿蒙应用中,实现网址打开操作,先后介绍了带参数的自定义构建函数的使用,调用系统浏览器的实现,以及如何封装 WebViewPage。值得重点学习的,理当首推封装 webViewPage 的部分,基于该部分,可以扩展地探索开发浏览器的实现方案。
相关文章:
从零开始开发纯血鸿蒙应用之网页浏览
从零开始开发纯血鸿蒙应用 〇、前言一、优化菜单交互1、BuilderFunction.ets2、改造 PageTitleBar 二、网址打开1、方式选择1、使用浏览器打开2、内部打开2.1、声明权限2.2、封装 WebViewPage2.2.1、组件字段2.2.2、aboutToAppear2.2.3、onBackPress2.2.4、标题栏2.2.4、网页内…...
【大模型LLM】DeepSeek LLM Scaling Open-Source Language Models with Longtermism
深度探索LLM:以长期主义扩展开源语言模型 0.论文摘要 开源大语言模型(LLMs)的快速发展确实令人瞩目。然而,以往文献中描述的扩展规律得出了不同的结论,这为LLMs的扩展蒙上了一层阴影。我们深入研究了扩展规律&#…...
分布式事务-本地消息表学习与落地方案
本文参考: 数据库事务系列04-本地消息表实现分布式事务 基础概念 本地消息表实现分布式事务最终一致性的核心:是通过上游本地事务的原子性持久性,配合中间件的重试机制,从而实现调用下游的最终一致性。 这里有几个要点可以解析一…...
Debezium系列之:记录一次源头数据库刷数据,造成数据丢失的原因
Debezium系列之:记录一次源头数据库刷数据,造成数据丢失的原因 一、背景二、查看topic日志信息三、结论四、解决方法一、背景 源头数据库在很短的时间内刷了大量的数据,部分数据在hdfs丢失了 理论上debezium数据采集不会丢失,就需要排查数据链路某个节点是否有数据丢失。 …...
PHP约课健身管理系统小程序源码
🏋️♂️ 约课健身管理系统小程序:重塑健身预约体验,引领数字化健身新时代 一款基于ThinkPHPUniapp框架,由米扬精心雕琢的约课健身管理系统小程序,专为健身房、健身工作室、运动会所、运动场馆、瑜伽馆、拳馆等泛健…...
Java之泛型
文章目录 首先接着上一篇(集合)文章,来个非常牛逼的易错题传统集合问题分析泛型快速入门案例泛型介绍泛型的好处泛型的语法泛型的声明泛型的实例化泛型使用举例泛型使用的注意事项和细节 自定义泛型自定义泛型方法 自定义泛型接口自定义泛型方…...
图论 之 最小生成树
文章目录 题目1584.连接所有点的最小费用 最小生成树MST,有两种算法进行求解,分别是Kruskal算法和Prim算法Kruskal算法从边出发,适合用于稀疏图Prim算法从顶点出发,适合用于稠密图:基本思想是从一个起始顶点开始&#…...
STM32-有关内存堆栈、map文件
STM32堆栈空间大小设置_stm32堆栈分配大小-CSDN博客 STM32堆栈的大小及内存四(五)区的分析 - 天街小雨润地狠 - 博客园 .map文件的位置...
Linux系统中常见的词GNU是什么意思?
GNU 是 “GNU’s Not Unix” 的递归缩写,它是一个自由软件项目,旨在创建一个完全自由的操作系统。这个名字反映了GNU项目的核心理念:它试图创建一个类Unix的系统,但不是Unix本身。 GNU 项目由 理查德斯托曼(Richard S…...
【个人开源】——从零开始在高通手机上部署sd(二)
代码:https://github.com/chenjun2hao/qualcomm.ai 推理耗时统计 单位/ms 硬件qnncpu_clipqnncpu_unetqnncpu_vaehtp_cliphtp_unethtp_vae骁龙8 gen124716.994133440.39723.215411.097696.327 1. 下载依赖 下载opencv_x64.tar,提取码: rrbp下载opencv_aarch64.t…...
【MCU驱动开发概述】
MCU驱动开发概述 目录 MCU驱动开发概述二、驱动开发的目的三、驱动开发的关键组成部分四、示例 - LED 控制驱动 一、引言 MCU(Microcontroller Unit),即微控制器单元,是一种集成在单个芯片上的计算机系统,通常用于控制…...
PC端Linux之虚拟CAN
在调试QT程序时候需要用到虚拟CAN进行发送和接收的操作,以此记录方法。 在调试QT程序时候需要用到虚拟CAN进行发送和接收的操作,以此记录方法。 1、安装can-utils sudo apt install can-utils ifconig -a【查看是否安装成功,是否有can0网络…...
C++:std::thread、条件变量与信号量
介绍 在多线程编程的世界里,协调不同线程之间的工作是一项极具挑战性的任务。线程可能需要等待特定条件的满足,或者对共享资源的访问进行限制。C 标准库为我们提供了强大的工具,如 std::thread 用于创建和管理线程,条件变量用于线…...
POI pptx转图片
前言 ppt页面预览一直是个问题,office本身虽然有预览功能但是收费,一些开源的项目的预览又不太好用,例如开源的:kkfileview pptx转图片 1. 引入pom依赖 我这个项目比较老,使用版本较旧 <dependency><gro…...
Java File 类
File 类是 Java 中用于处理文件和目录的基本类之一,位于 java.io 包中。它提供了多种方法来创建、删除、检查、修改文件或目录的属性,以及列出文件夹中的内容。虽然 File 类本身不提供直接的读取或写入文件内容的方法(这些操作通常由 FileInp…...
工业通信协议 EtherNet/IP 全面解析
工业通信协议 EtherNet/IP 全面解析 EtherNet/IP(以太网工业协议)是一种基于标准以太网的工业自动化通信协议,由 ODVA(开放设备网供应商协会) 管理。它融合了 CIP(通用工业协议) 和以太网技术&…...
使用docker配置PostgreSQL
配置docker阿里云镜像仓库 国内使用docker hub拉取镜像比较慢,所以首先配置个人的镜像仓库。 阿里云的个人镜像仓库是免费的,对个人来说足够用。 具体操作参考阿里云官方链接 。 关于个人镜像仓库的使用参考链接。 配置完个人镜像仓库后将公网配置到doc…...
UITextView删除原有字符串时,光标会上移并且光标会变高
代码运行效果如图: import Foundationclass TestVC: UIViewController {override func viewDidLoad() {super.viewDidLoad()let testV MyCustomTextView(frame: CGRect(x: 0, y: 130, width: SCREEN_WIDTH - 50, height: 170))self.view.addSubview(testV)testV.ba…...
python入门 介绍及变量的使用
1.python介绍 python 是一门计算机语言 常见的计算机语言:python、java、C语言。。。 什么是计算机语言:就是让计算机知道你想干什么,把你的需求使用它能听懂的语言说出来 中国也有一门计算机语言:易语言 能认为是语言的本质上…...
51单片机-按键
1、独立按键 1.1、按键介绍 轻触开关是一种电子开关,使用时,轻轻按开关按钮就可使开关接通,当松开手时,开关断开。 1.2、独立按键原理 按键在闭合和断开时,触点会存在抖动现象。P2\P3\P1都是准双向IO口,…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
