【每日学点HarmonyOS Next知识】getContext问题、清除Web缓存、弹层的点击事件透传、去除间隙、侧滑菜单设置

server/2025/3/5 8:32:28/

【每日学点HarmonyOS Next知识】getContext问题、清除Web缓存、弹层的点击事件透传、去除间隙、侧滑菜单设置

1、HarmonyOS getContext()获取不到?

在两个不同的页面分别使用bindPopup与bindSheet弹出相同的弹窗,点击弹窗中的按钮跳转H5页面,其中bindPopup会闪退,报错Error message:Cannot read property resourceManager of undefined SourceCode:const resourceManager = context.resourceManager; getContext()获取不到。而bindSheet正常打开h5页面

getContext()获取不到,导致resourceManager 为undefined
在ability内使用this.context
在ui侧可使用getcontext

2、HarmonyOS 如何清除Web缓存

如何清除Web组件加载网页后产生的资源(图片等)的缓存

可以使用removeCache()方法。参考地址:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-webview-V5#removecache

removeCache(clearRom: boolean): void
清除应用中的资源缓存文件,此方法将会清除同一应用中所有webview的缓存文件。

可以通过在data/storage/el2/base/cache/web/Cache目录下查看Webview的缓存

3、HarmonyOS 弹层的点击事件透传处理?

实现一套各个页面均可弹层的功能,涉及到弹层的点击事件透传处理
希望可以获取到点击的位置,弹层内的像素点,并获取到透明度,来判断点击事件是否需要透传到底部场景。
当前根据点击坐标获取透明度的整体链路,因组件截图api是异步接口,事件拦截需要同步接口,无法达成整体链路。

参考代码:

@Entry
@Component
struct HitTestPage {@State message: string = 'Hello World';build() {Stack() {Column().onTouch((event: TouchEvent)=> {if (event.type == TouchType.Down) {console.info("点击了:底部的界面")}}).height('100%').width('100%').backgroundColor(Color.Green)Column() {Text().backgroundColor(Color.Black).onTouch((event: TouchEvent)=> {event.stopPropagation()if (event.type == TouchType.Down) {console.info("点击了:文本")}}).height(100).width(100)}.onTouch((event: TouchEvent)=> {if (event.type == TouchType.Down) {console.info("点击了:上面的界面")}}).hitTestBehavior(HitTestMode.Transparent).backgroundColor(Color.Transparent).height('100%').width('100%')}.height('100%').width('100%')}
}
//Index.ets
import { PageTwo } from './pageTwo';export class NavParam {dialogHeightChangeBack?: (dialogHeight: number) => voidconstructor( dialogHeightChangeBack?: (dialogHeight: number) => void) {this.dialogHeightChangeBack = dialogHeightChangeBack}
}@Entry
@Component
struct Index {@State message: string = 'Hello World';@Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack()@StorageLink("windowHeight") windowHeight: number = 0@State contentHeight: number = 100;private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]@BuilderPageMap(name: string, param: NavParam) {if (name === 'pageTwo') {PageTwo({dialogHeightChangeBlock: param.dialogHeightChangeBack});}}aboutToAppear() {console.info("testTag: 当前windowHeight" + this,this.windowHeight);this.contentHeight = px2vp(this.windowHeight);}build() {Navigation(this.pageInfos) {Column() {Row().height(50)Button("pageOne").fontSize(30).type(ButtonType.Capsule).fontWeight(FontWeight.Bold).onClick(() => {this.pageInfos.pushPath({ name: 'pageTwo', param: new NavParam((dialogHeight: number) => {if (dialogHeight == 0) {animateTo({ duration: 250 }, () => {this.contentHeight = px2vp(this.windowHeight);})} else {this.contentHeight = px2vp(this.windowHeight) - dialogHeight;}})});})List({ space: 20, initialIndex: 0 }) {ForEach(this.arr, (item: number) => {ListItem() {Text('' + item).width('100%').height(100).fontSize(16).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)}}, (item: string) => item)}.listDirection(Axis.Vertical) // 排列方向.scrollBar(BarState.Off).friction(0.6).divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring.width('90%')}.justifyContent(FlexAlign.Center).width('100%').height(this.contentHeight).hitTestBehavior(HitTestMode.Transparent).onTouch((event: TouchEvent) => {if (event.type == TouchType.Down) {console.info('事件穿透:colume点击了')}})}.navDestination(this.PageMap).onTouchIntercept((event: TouchEvent) => {if (event.type == TouchType.Down) {console.info('事件穿透:navigation点击了')}return HitTestMode.Transparent})}
}//PageTwo.ets@Component
export struct PageTwo {@State isShow: boolean = true;gravity: Alignment = Alignment.BottomtransitionEdge: TransitionEdge = TransitionEdge.BOTTOM@Consume('pageInfos') pageInfos: NavPathStack;@State gestureHeight: number = 500;dialogHeightChangeBlock?: (dialogHeight: number) => void;private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]scrollOffsetY: number = 0;private scrollerForList: Scroller = new Scroller()@State canHandleScroll: boolean = true;aboutToAppear() {this.callBackHeight(this.gestureHeight);}callBackHeight(height: number) {if (this.dialogHeightChangeBlock) {this.dialogHeightChangeBlock!(height);}}build() {NavDestination() {//背景层Stack({ alignContent: this.gravity }) {//内容区Stack({ alignContent: this.gravity }) {if (this.isShow) {//手势层Stack({ alignContent: Alignment.Top }) {Column() {List({ space: 20, initialIndex: 0, scroller: this.scrollerForList }) {ForEach(this.arr, (item: number) => {ListItem() {Text('' + item).width('100%').height(100).fontSize(16).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)}}, (item: string) => item)}.enableScrollInteraction(this.canHandleScroll).listDirection(Axis.Vertical) // 排列方向.scrollBar(BarState.Off).friction(0.6).divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring.onScroll((scrollOffset: number, scrollState: ScrollState) => {this.scrollOffsetY += scrollOffset;console.info("list: y偏移量 " + this.scrollOffsetY);if (this.scrollOffsetY <= 0) {this.scrollerForList.scrollTo({xOffset:0,yOffset:0,animation:false});this.scrollOffsetY = 0;this.canHandleScroll = false;}}).height('100%').width('100%')}}.borderRadius(6).transition(TransitionEffect.move(this.transitionEdge).animation({ duration: 250, curve: Curve.Smooth })).position({ x: 0, y: 0 }).height("100%").width("100%").clip(true).backgroundColor(Color.White)}}.width("100%").height(this.gestureHeight).parallelGesture(PanGesture({ direction: PanDirection.Vertical, fingers: 1 }).onActionUpdate((event: GestureEvent) => {if (!this.canHandleScroll) {console.info("testTag: y偏移量 " + event.offsetY);let temHeight = 500;temHeight -= event.offsetY;if (temHeight >= 500) {this.gestureHeight = 500;} else {this.gestureHeight = temHeight;}this.callBackHeight(this.gestureHeight);}}).onActionEnd((event: GestureEvent) => {if (!this.canHandleScroll) {console.info("testTag: 动画结束y偏移量 " + event.offsetY);let temHeight = 500;temHeight -= event.offsetY;if (temHeight < 250) {this.closeDialogAction()} else if (temHeight >= 250 && temHeight < 500) {let duration = (500 - temHeight) / 500.0 * 250.0;animateTo({ duration: duration }, () => {this.gestureHeight = 500;this.callBackHeight(this.gestureHeight);})}this.canHandleScroll = true;}}))}.onClick(() => {// this.closeDialogAction()}).onTouchIntercept((event: TouchEvent) => {if (event.type == TouchType.Down) {console.info('事件穿透:stack点击了')}return HitTestMode.Transparent}).width('100%').height('100%').backgroundColor('#33000000')}.onBackPressed(() => {this.closeDialogAction()return true}).hitTestBehavior(HitTestMode.Transparent).onTouch((event: TouchEvent) => {if (event.type == TouchType.Down) {console.info('事件穿透:dialog点击了')}}).hideTitleBar(true).mode(NavDestinationMode.DIALOG)}closeDialogAction() {this.isShow = false;this.callBackHeight(0);animateTo({duration: 100, delay: 250, onFinish: () => {this.pageInfos.pop()}}, () => {})}
}//EntryAbility.etsimport { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';async function enterImmersion(windowClass: window.Window) {AppStorage.setOrCreate<number>('windowHeight', windowClass.getWindowProperties().windowRect.height)AppStorage.setOrCreate<number>('windowWidth', windowClass.getWindowProperties().windowRect.width)// 监听窗口高度变化windowClass.on('windowSizeChange', (size)=> {AppStorage.setOrCreate<number>('windowHeight', size.height)AppStorage.setOrCreate<number>('windowWidth', size.width)})// 设置窗口布局为沉浸式布局await windowClass.setWindowLayoutFullScreen(true)await windowClass.setWindowSystemBarEnable(["status", "navigation"])// 设置状态栏和导航栏的背景为透明await windowClass.setWindowSystemBarProperties({navigationBarColor: "#00000000",statusBarColor: "#00000000",})
}export default class EntryAbility extends UIAbility {onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');}onDestroy(): void {hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');}async onWindowStageCreate(windowStage: window.WindowStage) {// Main window is created, set main page for this abilityhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');let windowClass:window.Window = await windowStage.getMainWindow()await enterImmersion(windowClass)windowStage.loadContent('pages/Index', (err) => {if (err.code) {hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');});}onWindowStageDestroy(): void {// Main window is destroyed, release UI related resourceshilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');}onForeground(): void {// Ability has brought to foregroundhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');}onBackground(): void {// Ability has back to backgroundhilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');}
}
4、HarmonyOS 如何去除间隙?

如何去除虚拟键盘与自定义输入框dialog 之间的间隙

之所以设置安全距离,是因为自定义弹窗仅适用于简单提示场景,不能替代页面使用。由于弹窗存在完全避让输入法行为,即在软键盘弹出时,会自动向上抬起软键盘高度,因此如果弹窗高度过大时,可能会导致部分区域不可见。弹窗避让软键盘时,与软键盘之间存在16vp的安全间距。 结合文档说法,可以手动在软键盘弹起时设置offset:{y:16}来抵消安全距离。

参考demo:

//CustomDialog.ets
build{Column(){TextArea({text: "",placeholder: 'The text area can hold an unlimited amount of text. input your word...',controller: this.textController}).height(200).width("100%")}//todo 需要在 TextArea的外层组件设置 offset 来抵消安全距离.offset({y:16})
}
//规格选择页面控制器
customDialogController: CustomDialogController = new CustomDialogController({builder: SpecificationsCustomDialog({}),alignment: DialogAlignment.Bottom,customStyle: true,autoCancel: false,//这里设置dy: -16,会将弹窗抬起来offset: {dx: 0,dy: -16}
});
5、HarmonyOS ListItem侧滑菜单动态设置?

有一个list列表,列表项item有侧滑菜单,但是编辑状态下又没有侧滑菜单,想通过一个开关动态设置侧滑菜单

参考demo:

@Entry
@Component
struct ListItemExample2 {@State arr: number[] = [0, 1, 2, 3, 4]@State enterEndDeleteAreaString: string = "not enterEndDeleteArea"@State exitEndDeleteAreaString: string = "not exitEndDeleteArea"@State isShow:boolean = true;@Builder itemEnd() {Row() {Button("Delete").margin("4vp")Button("Set").margin("4vp")}.padding("4vp").justifyContent(FlexAlign.SpaceEvenly)}build() {Column() {Button("点击").onClick(()=>{this.isShow=!this.isShowconsole.log(this.isShow+"111111111")})List({ space: 10 }) {ForEach(this.arr, (item: number) => {ListItem() {Text("item" + item).width('100%').height(100).fontSize(16).textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF)}.transition({ type: TransitionType.Delete, opacity: 0 }).swipeAction({end: this.isShow?{builder: () => { this.itemEnd() },onAction: () => {animateTo({ duration: 1000 }, () => {let index = this.arr.indexOf(item)this.arr.splice(index, 1)})},actionAreaDistance: 56,onEnterActionArea: () => {this.enterEndDeleteAreaString = "enterEndDeleteArea"this.exitEndDeleteAreaString = "not exitEndDeleteArea"},onExitActionArea: () => {this.enterEndDeleteAreaString = "not enterEndDeleteArea"this.exitEndDeleteAreaString = "exitEndDeleteArea"}}:undefined})}, (item: string) => item)}Text(this.enterEndDeleteAreaString).fontSize(20)Text(this.exitEndDeleteAreaString).fontSize(20)}.padding(10).backgroundColor(0xDCDCDC).width('100%').height('100%')}
}

http://www.ppmy.cn/server/172556.html

相关文章

SpringCloud系列教程(十二):网关配置动态路由

除了token以外&#xff0c;还有一个很实用的功能就是把网关的路由配置放到nacos上&#xff0c;并且修改路由配置的时候&#xff0c;网关服务可以动态的更新&#xff0c;这样我们在调整网络配置的时候&#xff0c;就不用重启服务了。所以我们需要用到两个重要的类&#xff1a;Na…

中科大计算机网络笔记第一章1.8 互联网历史笔记

计算机网络与互联网历史概述 一、早期通信方式 1. 线路交换 ‌时间‌&#xff1a;1960年之前‌特点‌&#xff1a; 线路建立时间长&#xff0c;代价高。线路资源独享&#xff0c;不适合突发性强的计算机通信。可靠性不高&#xff0c;核心节点损毁影响大。 二、分组交换理论的…

物理竞赛中的线性代数

线性代数 1 行列式 1.1 n n n 阶行列式 定义 1.1.1&#xff1a;称以下的式子为一个 n n n 阶行列式&#xff1a; ∣ A ∣ ∣ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n ∣ \begin{vmatrix}\mathbf A\end{vmatrix} \begin{vmatrix} a_{11…

翻译: 深入分析LLMs like ChatGPT 二

监督微调&#xff08;SFT&#xff09; 使用人工标注的对话数据集&#xff08;如1M条"用户-助手"对话&#xff09;继续训练模型。 标注员遵循指导原则编写理想回答&#xff0c;使模型学习助手的回应风格。 示例对话格式&#xff1a; [系统] 你是一个有帮助的AI助手……

Apache Kafka单节点极速部署指南:10分钟搭建开发单节点环境

Apache Kafka单节点极速部署指南&#xff1a;10分钟搭建开发单节点环境 Kafka简介&#xff1a; Apache Kafka是由LinkedIn开发并捐赠给Apache基金会的分布式流处理平台&#xff0c;现已成为实时数据管道和流应用领域的行业标准。它基于高吞吐、低延迟的设计理念&#xff0c;能够…

uploadlabs经验总结

目录 一、基础上传漏洞&#xff08;太过简单目前环境不可能存在&#xff09; 1、抓包然后改后缀进行绕过 2、抓包然后改上传文件类型进行绕过 3、改后缀大小写绕过&#xff0c;以及收尾加空格&#xff0c;加::$DATA,加点等等 4、黑名单不完整绕过&#xff0c;复习后缀绕过&…

【网络安全】——二进制协议 vs 文本协议:从原理到实战的深度解析

目录 引言 一、协议的本质与分类 二、二进制协议详解 1. 核心特点 2. 典型结构示例 3. 常见应用场景 4. 详细介绍 三、文本协议详解 1. 核心特点 2. 典型结构示例 3. 常见应用场景 4.详细介绍 四、关键对比&#xff1a;二进制协议 vs 文本协议 五、实战案例&…

05 HarmonyOS NEXT高效编程秘籍:Arkts函数调用与声明优化深度解析

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; 目录 概述函数调用优化声明参数要和实际的参数一致反例正例 函数内部变量尽量使用参数传递反例正例 函数与类声明优化避免动态声明function与class…