纯血鸿蒙APP实战开发——预渲染实现Web页面瞬开效果

news2024/10/6 0:30:31

介绍

为了便于大家在使用本案例集时能够更详细的了解各个案例,本案例基于Web预渲染实现了案例介绍功能,即应用右下角的问号icon。

效果图预览

使用说明

  1. 因为直接加载的线上README,因此本功能需联网使用
  2. 点击icon,即会弹出对应案例的README
  3. 按钮可拖动
  4. 返回或下拉bindSheet上方的dragBar可隐藏帮助页

案例适配说明

为确保案例正确显示其README,请确保entry模块的依赖中@ohos/xxx中的xxx与案例目录名相同

实现思路

  1. 使用Stack承载Navigation,从而使得icon能够在应用的各个案例(NavDestination承载)上显示。源码见EntryView.ets
    Stack() {
      Navigation(this.pageStack) {
      //...
      }
      // 帮助功能:在每个案例的右下角添加“帮助”功能
      HelperView()
    }
    
  2. 使用BindSheet+WebView加载仓上各模块README。源码见HelperView.ets
    build() {
      Image($r("app.media.help"))
        .bindSheet($$this.isShowReadMe, this.buildReadMeSheet(), {
          //...
      })
    }
    
    @Builder
    buildReadMeSheet(): void {
      //...
    }
    
  3. 使用webview预渲染提升用户体验,复用webview实例减少资源占用。源码见NWebUtils.ets
    /**
     * Builder中为动态组件的具体组件内容
     * 调用onActive,开启渲染
     */
    @Builder
    function WebBuilder(data: Data) {
      Web({ src: data.url, controller: data.controller })
        .onPageBegin(() => {
          data.controller.onActive();
        })
        .width($r("app.string.full_size"))
        .height($r("app.string.full_size"))
    }
    
    
    const wrap: WrappedBuilder<Data[]> = wrapBuilder<Data[]>(WebBuilder);
    
    /**
     * 用于控制和反馈对应的NodeContainer上的节点的行为,需要与NodeContainer一起使用
     */
    export class NWebNodeController extends NodeController {
      private rootNode: BuilderNode<Data[]> | null = null;
    
      /**
       * 必须要重写的方法,用于构建节点数、返回节点挂载在对应NodeContainer中
       * 在对应NodeContainer创建的时候调用、或者通过rebuild方法调用刷新
       */
      makeNode(uiContext: UIContext): FrameNode | null {
        if (this.rootNode) {
          return this.rootNode.getFrameNode();
        }
        return null; // 返回null控制动态组件脱离绑定节点
      }
    
      /**
       * 自定义函数,可作为初始化函数使用
       * 通过UIContext初始化BuilderNode,再通过BuilderNode中的build接口初始化@Builder中的内容
       */
      initWeb(url: string, uiContext: UIContext, controller: WebviewController) {
        if (this.rootNode) {
          return;
        }
        // 创建节点与动态web组件
        this.rootNode = new BuilderNode(uiContext);
        this.rootNode.build(wrap, { url: url, controller: controller });
      }
    }
    
    interface CurrentNode {
      url: string | null;
      webController: webview.WebviewController | null;
      nWebController: NWebNodeController | null;
      lastNetAvailable: boolean;
    }
    
    /**
     * 复用webview
     */
    function loadUrl(url: string): void {
      if (currentNode.webController) {
        currentNode.url = url;
        currentNode.webController.loadUrl(url);
      }
    }
    
    // 当前的Node
    const currentNode: CurrentNode = { url: null, nWebController: null, webController: null, lastNetAvailable: true };
    
    /**
     * 销毁相关资源
     */
    export function clearHelperWeb() {
      currentNode.url = null;
      currentNode.webController = null;
      currentNode.nWebController = null;
    }
    
    /**
     * 创建web实例,如果已经存在web实例,复用
     * @param url
     * @param uiContext
     */
    export function createNWeb(url: string, uiContext: UIContext): void {
      if (currentNode.webController && currentNode.nWebController && currentNode.url !== url || !currentNode.lastNetAvailable) {
        loadUrl(url);
        currentNode.lastNetAvailable = connection.hasDefaultNetSync();
        return;
      }
      clearHelperWeb();
      let baseNode = new NWebNodeController();
      let controller = new webview.WebviewController();
      // 初始化自定义web组件
      baseNode.initWeb(url, uiContext, controller);
      currentNode.url = url;
      currentNode.webController = controller;
      currentNode.nWebController = baseNode;
      currentNode.lastNetAvailable = connection.hasDefaultNetSync();
    }
    
    /**
     * 获取NodeController
     */
    export function getNWeb(url: string): NWebNodeController | null {
      if (currentNode.url != url || !currentNode.lastNetAvailable) {
        loadUrl(url);
      }
      currentNode.lastNetAvailable = connection.hasDefaultNetSync();
      return currentNode.nWebController;
    }
    
    /**
     * 停止页面加载:当url频繁切换时使用
     */
    export function stopWebLoad(): void {
      if (currentNode.url && currentNode.webController) {
        currentNode.webController.stop();
      }
    }
    
  4. 监听NavPathStack的变更,及时切换url。源码见HelperView.ets
    onPageStackChange(): void {
      if (!this.pageStack.size()) {
        this.helperUrl = HelperConstants.HELPER_URL_HOME;
      } else {
        const size: number = this.pageStack.size();
        let moduleName: string = this.pageStack.getAllPathName()[size-1].split('/')[1];
        this.helperUrl = HelperConstants.HELPER_URL_PROTOTYPE.replace("{placeholder}", moduleName);
      }
    }
    

参考资料

  1. web预渲染
  2. bindSheet

鸿蒙全栈开发全新学习指南

也为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大APP实战项目开发】

本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:https://gitee.com/MNxiaona/733GH

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:gitee.com/MNxiaona/733GH

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

鸿蒙入门教学视频:

美团APP实战开发教学:gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

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

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

相关文章

跟TED演讲学英文:The secret ingredient of business success by Pete Stavros

The secret ingredient of business success Link: https://www.ted.com/talks/pete_stavros_the_secret_ingredient_of_business_success? Speaker: Pete Stavros Date: April 2024 文章目录 The secret ingredient of business successIntroductionVocabularyTranscriptSu…

前端框架技术调研

目前程序员使用前端框架最多的是哪一个&#xff1f;

WCH RISC CH32V303RCT6 单片机的SDI Printf 虚拟串口功能 类似SEGGER RTT打印功能 简单分析

参考&#xff1a; 有关于 SDI printf 更多的信息和资料吗&#xff1f; 关于 CH32 系列 MCU SDI 虚拟串口功能的使用 【CH32X035 评估板测评】 教你使用 SDI 接口重定向 printf SDI (Serial Data Interface) 是沁恒微电子 RISC-V 内核的私有外设接口,CH32 RISC-V 系列目前提供了…

最佳WordPress外贸主题推荐(2024)

WordPress是一个非常受欢迎的建站平台&#xff0c;它具有易用性&#xff0c;并提供了许多功能强大的主题和插件。如果你计划建立一个外贸独立站商城&#xff0c;选择一个适合的WordPress外贸主题至关重要。以下是一些外贸主题应具备的特点&#xff1a; 1. 欧美风格&#xff1a…

一套JAVA语言开发的:危大工程智慧一体化工地系统源码,(后台管理端+APP+可视化大屏端)

智慧工地是指利用移动互联、物联网、智能算法、地理信息系统、大数据挖掘分析等信息技术&#xff0c;提高项目现场的“人•机•料•法•环•安”等施工要素信息化管理水平&#xff0c;实现工程施工可视化智能管理&#xff0c;并逐步实现绿色生态建造。 相关技术&#xff1a;微…

【MATLAB源码-第200期】基于matlab的鸡群优化算法(CSO)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 鸡群优化算法&#xff08;Chicken Swarm Optimization&#xff0c;简称CSO&#xff09;是一种启发式搜索算法&#xff0c;它的设计灵感来源于鸡群的社会行为。这种算法由Xian-bing Meng等人于2014年提出&#xff0c;旨在解决…

【第 8 节】大模型微调数据构造(补充课程)

1 简介 视频课程 | 操作文档 | OpenDataLab 2 课程内容 2.1 大模型训练数据 2.2 微调 pretrain数据集 - 万卷 SFT 微调相关 TO-DO&#xff1a;2024.5左右会开源一个LLM标注工具。 密切关注opendatalab 2.3 微调数据构造 数据质量判断 tips&#xff1a; 弱智吧&#xff1a…

【论文】关于网页上能打开的文章下载PDF“显示无效或损坏的 PDF 文件”的解决办法

1. 遇到的问题 今天我在 dl.acm.org/doi 下载论文时发现下载后的pdf打开出现“显示无效或损坏的 PDF 文件” 可是在原网址是可以打开并显示的 2. 解决方案 这里我用到了和之前【论文】去除PDF论文行号的完美解决方案 的相似的解决办法 就是下载的时候不直接下载&#xf…

【兼职宝典】七大靠谱手机兼职副业平台,让你乐在其中,轻松实现财务自由!

数字化时代已经到来&#xff0c;互联网的普及与技术的飞速发展让越来越多的人开始关注兼职工作&#xff0c;以此增加收入、锻炼能力或追求兴趣爱好。本文将为您详细解读几种热门的兼职方式&#xff0c;助您找到最适合自己的兼职岗位。 一&#xff0c;自媒体运营&#xff1a;创…

python使用opencv对图像的基本操作(3)

17.颜色空间的转换 17.1.rgb图像转gray图像 from skimage import io,color img io.imread(lbxx.jpg) img_gray color.rgb2gray(img) #将rgb图像转换成gray图像 io.imshow(img_gray)运行结果&#xff1a; 17.2.rgb图像转hsv图像 from skimage import io,color img io.im…

Python多线程编程深度探索:从入门到实战

title: Python多线程编程深度探索&#xff1a;从入门到实战 date: 2024/4/28 18:57:17 updated: 2024/4/28 18:57:17 categories: 后端开发 tags: 多线程并发编程线程安全Python异步IO性能优化实战项目 第1章&#xff1a;Python基础知识与多线程概念 Python简介&#xff1a…

WPF 6 命令

命令 创建一个按钮&#xff0c;新建一个事件&#xff0c;按住F12 就可以添加业务代码 运行代码 此时希望UI与后台代码分离&#xff0c;互不影响 此时新建一个MainViewModel类&#xff0c;来保存业务代码 Icommand 是所有command的父类接口 新建一个command来实现这个接口…

怎么才能让数字在横线上缩小了数字还在横线上

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>刻度</title> </head> <style typ…

遇到软件测试职业瓶颈,如何突破

作为职场人&#xff0c;遇到发展瓶颈是在所难免的&#xff0c;无论是晋升受限、技能升级缓慢&#xff0c;还是工作激情的丢失&#xff0c;这些挑战都可能让人感到挫败。但是&#xff0c;积极应对&#xff0c;你就可能找到那扇通向新机遇的窗。 1. 自我评估 识别问题 是缺乏技…

武汉星起航:挂牌上海股权中心,开启资本新篇章助力跨境电商飞跃

2023年10月30日&#xff0c;武汉星起航电子商务有限公司在上海股权托管交易中心成功挂牌展示&#xff0c;标志着这家在跨境电商领域拥有卓越声誉的企业正式迈入了资本市场的大门。对于武汉星起航来说&#xff0c;这不仅是其发展历程中的一个重要里程碑&#xff0c;更是对其业务…

<计算机网络自顶向下> Internet Protocol(未完成)

互联网中的网络层 IP数据报格式 ver: 四个比特的版本号&#xff08;IPV4 0100, IPV6 0110&#xff09; headlen&#xff1a;head的长度&#xff08;头部长度字段&#xff08;IHL&#xff09;指定了头部的长度&#xff0c;以32位字&#xff08;4字节&#xff09;为单位计算。这…

mysql 开启远程连接

登录到mysql mysql -uroot -p 打开mysql数据库并查询user表 use mysql; select user, host from user;更改需要远程连接数据库为任何ip 可以连接&#xff0c; 并刷新系统权限相关的表 update user set host% where hostlocalhost and userroot; flush privileges;

算法课程笔记——如何倍增

快速幂 读入量大于1e5不要用cin读入&#xff0c;要用也要关闭同步流 第i个o次方的父亲 #include<bits/stdc.h>usingnamespacestd; #definemaxn 110000#definell long longintn, a[maxn], f[maxn][40]; intquery(intl, intr){intk (int)(log((r - l 1) * 1.0) / log(2.0…

第3篇:创建Nios II工程之Hello_World<二>

Q&#xff1a;上一期介绍完基本设计流程和实验原理&#xff0c;接着我们完成系统硬件设计部分&#xff0c;包括Platform Designer系统及Quartus工程。 A&#xff1a;依次搜索并添加Nios II Processor、JTAG UART、On-Chip Memory和System ID IP组件&#xff0c;连接各组件并As…

扫码分享文件效果怎么做?文件转换成二维码的教程

文件如何快速分享并通过手机查看呢&#xff1f;传统方式一般会通过微信、QQ或者网盘的方式来分享在线内容&#xff0c;但是这种方式需要占用获取内容者的存储空间&#xff0c;所以很多人现在会通过文件转二维码的方式&#xff0c;将二维码分享后通过扫码来获取文件内容。这种方…