当前位置: 首页 > news >正文

佛山网站建设设计公司陕西住建执业证书官网

佛山网站建设设计公司,陕西住建执业证书官网,网站建设基本流程详细说明,动易网站系统怎么样往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录) ✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~ ✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~

✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记录一场鸿蒙开发岗位面试经历~

✏️ 持续更新中……


场景描述

透明页面也可以叫做弹窗页面,实际开发场景中经常有一个页面覆盖在另一个页面上的效果,例如:评论弹窗页面、广告弹窗页面等。

场景:评论弹窗页面

功能点:

  • 弹窗页面拉起。
  • 评论页面状态持久化保存。
  • 带参页面拉起。

方案一:使用router+subWindow实现

router路由无法更改页面模式,所以无法直接实现透明页面,需要借助拉起子窗口的方案实现透明页面的效果。思路如下:

  1. 获取窗口实例。

  2. 拉起一个子窗口并加载对应页面。

  3. 设置子窗口背景透明。

  4. 定义子窗口的关闭方案。

核心代码

在Ability中获取windowStage实例。

onWindowStageCreate(windowStage: window.WindowStage): void {// Main window is created, set main page for this abilitywindowStage.loadContent('pages/Index', (err) => {// 这里需要注意为了确保windowStage实例获取成功,我们最好在loadContent回调中回去,能保证页面加载成功的时候一定能讲windowStage实例存到AppStorage对象中AppStorage.setOrCreate("windowStage", windowStage);});}

创建一个子窗口作为页面载体,并加载RouterOpacityPage页面。

private windowClass: window.WindowStage | null = nullaboutToAppear(): void {this.windowClass = AppStorage.get("windowStage") as window.WindowStage;}build() {...Button("使用router路由").onClick(() => {this.windowClass?.createSubWindow("routerOpacityPage", (err, win) => {win.setUIContent('pages/RouterOpacityPage');win.showWindow();})})...}

加载页面后,这时候出现的新页面发现并不是透明的,那么我们把页面跟容器设置背景颜色为透明,也没有效果,根因是窗口默认是不透明的,需要设置窗口背景色。

@Entry@Componentstruct RouterOpacityPage {aboutToAppear(): void {// 设置当前窗口背景透明window.findWindow("routerOpacityPage").setWindowBackgroundColor("#00000000");}build() {...}}

需要注意的是,子窗口无法与主窗口事件交互,并且默认的手势返回也无法销毁,所以需要自己监听页面的返回手势来销毁子窗口来实现回到原页面的效果。

onBackPress(): boolean | void {// 这里解释下为什么需要用显示动画,因为窗口消失的时候无法对窗口添加动画,在转场动画中动画结束回调不生效,所以只能通过显示动画来控制组件显影然后在结束回调同销毁窗口animateTo({duration: 300, onFinish: () => {window.findWindow("routerOpacityPage").destroyWindow().then((res) => {console.log("destroyWindow success");}).catch(() => {console.log("destroyWindow fail");})}}, () => {this.opacityValue = 0;})return true;}

RouterOpacityPage 完整代码如下:

import { window } from '@kit.ArkUI'@Entry@Componentstruct RouterOpacityPage {@State opacityValue: number = 1;aboutToAppear(): void {// 设置当前窗口背景透明window.findWindow("routerOpacityPage").setWindowBackgroundColor("#00000000");}onBackPress(): boolean | void {// 这里解释下为什么需要用显示动画,因为窗口消失的时候无法对窗口添加动画,在转场动画中动画结束回调不生效,所以只能通过显示动画来控制组件显影然后在结束回调同销毁窗口animateTo({duration: 300, onFinish: () => {window.findWindow("routerOpacityPage").destroyWindow().then((res) => {console.log("destroyWindow success");}).catch(() => {console.log("destroyWindow fail");})}}, () => {this.opacityValue = 0;})return true;}build() {Column() {Column() {Text("页面2").fontSize(50).fontWeight(FontWeight.Bold)}.backgroundColor(Color.White).borderRadius(20).width("80%").height("60%").justifyContent(FlexAlign.Center)}.opacity(this.opacityValue).justifyContent(FlexAlign.Center).height('100%').width('100%').backgroundColor("#60000000").transition(TransitionEffect.OPACITY.animation({ duration: 300 }))}}

以上使用subWindow的方案实现了一个简单的透明页面效果,实际场景中可能还涉及到页面的持久化与参数传递。

页面持久化方案

上面代码中,我们在退出页面的时候使用的window.destroyWindow()方法,会导致整个窗口实例销毁,无法保存页面中的状态,这里我们需要使用window.minimize()方法来隐藏子窗口,而不是销毁子窗口,相关代码如下:

import { window } from '@kit.ArkUI';import CommentComponent from '../component/CommentComponent';@Entry@Componentstruct OpacityPage {@State opacityValue: number = 1;@State initialIndex: number = 0;onBackPress(): boolean | void {this.closeSubWindow();return true;}onPageShow(): void {this.opacityValue = 1;}closeSubWindow() {animateTo({duration: 300, onFinish: () => {// 当转场动画结束的时候执行窗口隐藏效果,注意这里不能使用destroyWindow销毁当前窗口,因为窗口销毁会导致page状态消失window.findWindow("OpacityPage").minimize().then((res) => {console.log("minimizeWindow success");}).catch(() => {console.log("minimizeWindow fail");})}}, () => {this.opacityValue = 0;})}build() {Column() {Column() {CommentComponent({ initialIndex: this.initialIndex })}.backgroundColor(Color.White).borderRadius(20).width("80%").height("60%").justifyContent(FlexAlign.Center).onClick(() => {})}.opacity(this.opacityValue).animation({ duration: 300 }).justifyContent(FlexAlign.Center).height('100%').width('100%').backgroundColor("#60000000").transition(TransitionEffect.OPACITY.animation({ duration: 300 })).onClick(() => {this.closeSubWindow()})}}

实现效果如下所示:

页面参数传递方案

因为窗口之前没有提供数据传递的API,所以无法直接传递页面参数;但是每个窗口都有自己的UIContext,可以通过UIContext获取其他窗口的router路由栈,并进行参数传递操作,但是因为该方案会造成不必要是内存消耗,影响性能,并且实现起来较复杂这里只提供思路,不做具体实现,相关功能在navigation路由中实现。

方案二:使用DIALOG类型NavDestination实现【推荐】

使用navigation作为路由框架时,实现透明页面只需要设置页面的NavDestinationMode属性为DIALOG模式思路如下:

  1. 使用navigation作为页面跟容器。

  2. 跳转NavDestination页面并设置其mode属性为NavDestinationMode.DIALOG。

  3. 添加自定义转场动画。这里使用的组件转场,可根据实际需要替换为navigation的自定义转场。

核心代码

使用navigation作为跟页面容器。

import { window } from '@kit.ArkUI';@Entry@Componentstruct Index {pageInfos: NavPathStack = new NavPathStack();build() {Navigation(this.pageInfos) {Column({ space: 8 }) {Button("使用navigation路由").onClick(() => {this.pageInfos.pushPath({ name: 'RouterOpacityPage2' });})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}.height('100%').width('100%').hideTitleBar(true).hideBackButton(true).hideToolBar(true)}}

子页面设置当前的页面模式为DIALOG模式。

@Builderexport function RouterOpacityPage2Builder(name: string, param: Object) {RouterOpacityPage2();}@Componentexport struct RouterOpacityPage2 {@State opacityValue: number = 1;pageInfos: NavPathStack = new NavPathStack();build() {NavDestination() {Column() {Column() {Text("页面2").fontSize(50).fontWeight(FontWeight.Bold)}.width('80%').height('60%').backgroundColor(Color.White).borderRadius(20)}.width("100%").height("100%").backgroundColor("#60000000").justifyContent(FlexAlign.Center).expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]).opacity(this.opacityValue)// 这里的动画可以使用navigation的自定义转场来实现,这里主要针对透明页面效果,动画效果不深入探讨实现.transition(TransitionEffect.OPACITY.animation({ duration: 300 }))}// 这里设置当前页面模式为DIALOG模式,默认情况下DIALOG模式就是透明页面.mode(NavDestinationMode.DIALOG).hideTitleBar(true).onBackPressed(() => {// 与第一种实现方式一样,这里也是用显示动画实现消失动画,具体场景也可以根据自己需要替换为navigation的自定义转场动画实现animateTo({duration: 300, onFinish: () => {this.pageInfos.pop();}}, () => {this.opacityValue = 0;})return true;}).onReady((context: NavDestinationContext) => {this.pageInfos = context.pathStack;})}}

同样的上面实现了一个最简单案例,但是我们实际开发过程中会涉及到参数传递与持久化状态的问题,navigation的参数传递就简单多了,我们在使用NavPathStack.pushPath跳转的时候就传递参数即可,代码如下:

Button("使用navigation路由带参数").onClick(() => {this.pageInfos.pushPath({ name: 'RouterOpacityPage2', param: 10 });})

RouterOpacityPage2页面接受参数代码如下:

在NavDestination.onShow生命周期中获取路由栈里面的参数信息即可。

@Componentexport struct RouterOpacityPage2 {@State initialIndex: number = 0;pageInfos: NavPathStack = new NavPathStack();build() {NavDestination() {...}.onShown(() => {if (this.pageInfos.getParamByName("RouterOpacityPage2")[0]) {this.initialIndex = this.pageInfos.getParamByName("RouterOpacityPage2")[0] as number;} else {this.initialIndex = 0;}})}}

页面持久化方案是不销毁透明页面(RouterOpacityPage2)在路由栈中的信息,即返回首页(HomePage)的时候不要使用NavPathStack.pop方法让页面出栈,而是找到NavPathStack中首页(HomePage)的路由信息使用NavPathStack.push回到首页,这样透明页面(RouterOpacityPage2)在路由栈中的信息不会消失,我们在RouterOpacityPage2中的操作就可以持久化的保存下来,再次打开的时候就会回到我们上次关闭时的状态,相关实现代码如下:

Button("使用navigation带参数持久化").onClick(() => {// 实现页面持久化需要使用navigation单例路由模式,当前暂无相关接口直接实现需要手动实现let homeIndex = this.pageInfos.getIndexByName("RouterOpacityPage2");if (homeIndex.length == 0) {this.pageInfos.pushPath({ name: 'RouterOpacityPage2', param: 10 }, false);return;}// 找到路由栈中RouterOpacityPage2的index使用moveIndexToTop接口移动到顶层让其显示this.pageInfos.moveIndexToTop(homeIndex.pop(), false)})@Componentexport struct RouterOpacityPage2 {@State opacityValue: number = 1;@State initialIndex: number = 0;pageInfos: NavPathStack = new NavPathStack();build() {NavDestination() {...}.onBackPressed(() => {animateTo({duration: 300, onFinish: () => {if (this.initialIndex) {// 实现页面持久化需要使用navigation单例路由模式,当前暂无相关接口直接实现需要手动实现let homeIndex = this.pageInfos.getIndexByName("HomePage");if (homeIndex.length == 0) {this.pageInfos.pushPath({ name: "HomePage" }, false);return;}this.pageInfos.moveIndexToTop(homeIndex.pop(), false);} else {this.pageInfos.pop();}}}, () => {this.opacityValue = 0;})return true;})}}

注意:上面的方式使用时RouterOpacityPage2会一直存在路由栈中,为避免不必要的内存消耗可以根据需要在不需要持久保存的时候对路由栈进行pop出栈处理。

实现效果如下:

http://www.dtcms.com/a/576948.html

相关文章:

  • Rust编程学习 - 自动解引用的用处,如何进行“解引用”(Deref) 是“取引用”(Ref) 的反操作
  • 云计算产品-介绍--网络/CDN篇
  • 云计算产品-介绍--安全篇
  • 3D模型骨骼绑定与动画完全指南-web平台
  • RabbitMQ 是否也支持消费组
  • 德国域名申请网站网站建设 推广薪资
  • 从零开始搭建 flask 博客实验(常见疑问)
  • 给予虚拟成像台尝鲜版十,完善支持HTML原型模式
  • ⸢ 拾叁-Ⅰ⸥⤳ 安全水位评估框架(上):威胁路径模型
  • 【Python Web开源框架】Django/Flask/FastAPI/Tornado/Pyramid
  • 拼多多seo搜索优化西安网站seo技术
  • DocxFactory: 一个C++操作word的开源库(不依赖office控件)
  • layui框架中,表单元素不显示问题
  • 主流模型调用
  • AI+XR赋能智慧研创中心:打破职业教育实训困境,推动产教深度融合
  • 网站的注册和登录怎么做军事热点最新情况
  • 在Powershell或CMD中使用conda命令
  • 体力劳动反而更难被AI取代?物联网科技如何守护最后的劳动阵地
  • 【代码审计】oasys 两处安全问题分析
  • 【IO多路转接】epoll 高性能网络编程:从底层机制到服务器实战
  • python --两个文件夹文件名比对(yolo 图和label标注比对检查)
  • 北京网站建设1000zhu建站之星模板怎么设置
  • wordpress+企业站模版做论坛app网站
  • 社群时代下的商业变革:“开源AI智能名片链动2+1模式S2B2C商城小程序”的应用与影响
  • 深入理解浏览器渲染流程:从HTML/CSS到像素的奇妙旅程
  • Photoshop - Photoshop 工具栏(24)磁性套索工具
  • 抓取QNX的RAMdump数据如何操作
  • RabbitMQ Quorum 队列与classic队列关系
  • ubuntu摄像头型号匹配不上_11-6
  • Design Compiler:时钟树在综合时的特性