写点什么

【每日学点 HarmonyOS Next 知识】类型判断、刘海高度、隐私弹窗、滑动下一页效果、清楚缓存

作者:轻口味
  • 2025-03-15
    北京
  • 本文字数:8020 字

    阅读完需:约 26 分钟

【每日学点HarmonyOS Next知识】类型判断、刘海高度、隐私弹窗、滑动下一页效果、清楚缓存

1、HarmonyOS instanceof 判断错误?

ArkTS 部分支持 instanceof,可参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/typescript-to-arkts-migration-guide-V5


instanceof 运算符在传递的过程中可能会发生以下情况:对象的属性在传递的过程中被修改。对象的引用在传递的过程中被改变。对象的构造函数可能尚未完成执行,导致对象状态不完整。以上情况都可能导致在接收线程中使用 instanceof 进行类型判断时出现错误。因此,直接依赖 instanceof 进行类型判断不够安全。

2、HarmonyOS 下刘海的高宽获取不到?

通过 window.getWindowAvoidArea(window.AvoidAreaType.TYPE_CUTOUT) 获取刘海的高宽的时候,没有取到下刘海的数据。


获取导航栏高度,设置 window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR

3、HarmonyOS 有没有隐私政策弹框的 demo?

可以使用 Stack 组件模拟实现 Dialog 的效果,页面跳转之后返回 可以做到 Dialog 依然显示的效果


import router from '@ohos.router';
@Entry@Componentstruct First { @State textValue: string = 'Hello World' // 显隐控制设置为不占用 @State visible: Visibility = Visibility.None @State path: string = "pages/Index"
build() { // 使用stack可以实现假的dialog覆盖原页面上面 Stack() { Row() { // 初始页面 Column() { Text('Hello World') .fontSize(50) .fontWeight(FontWeight.Bold) // 触发dialog的地方 Button('click') .onClick(() => { //用于检测点击事件是否透传到原来的页面,我测了一下是没有透传的,符合dialog规范 console.log("hit me!") if (this.visible == Visibility.Visible) { this.visible = Visibility.None } else { this.visible = Visibility.Visible } }) .backgroundColor(0x777474) .fontColor(0x000000) } .width('100%') } .height('100%') .backgroundColor(0x885555)
//这里开始是构造弹窗效果主要需要修改的地方,首先是加了一个半透明灰色的蒙层效果 Text('') .onClick(() => { if (this.visible == Visibility.Visible) { this.visible = Visibility.None } else { this.visible = Visibility.Visible } }) .width('100%') .height('100%')// 透明度可以自己调节一下 .opacity(0.16) .backgroundColor(0x000000) .visibility(this.visible) Column() { // 这个可以调节对话框效果,栅格布局,xs,sm,md,lg分别为四种规格 // 下面的breakpoints是用来区别当前属于哪个类型的断点 // gridRow里的栅格数量为总数,gridCol里的就是偏移和假Dialog所占据的栅格数 GridRow({ columns: { xs: 1, sm: 4, md: 8, lg: 12 }, breakpoints: { value: ["400vp", "600vp", "800vp"], reference: BreakpointsReference.WindowSize }, }) { GridCol({ span: { xs: 1, sm: 2, md: 4, lg: 8 }, offset: { xs: 0, sm: 1, md: 2, lg: 2 } }) { // 这里放的就是原Dialog里的column里的东西,稍微改改应该就可以用了 Column() { Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 }) TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%') .onChange((value: string) => { this.textValue = value }) Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 }) Flex({ justifyContent: FlexAlign.SpaceAround }) { Button('cancel') .onClick(() => { if (this.visible == Visibility.Visible) { this.visible = Visibility.None } else { this.visible = Visibility.Visible } }).backgroundColor(0xffffff).fontColor(Color.Black) Button('jump') .onClick(() => { router.pushUrl({ //url: 'pages/Index' url: this.path }) }).backgroundColor(0xffffff).fontColor(Color.Red) }.margin({ bottom: 10 }) } .backgroundColor(0xffffff) .visibility(this.visible) .clip(true) .borderRadius(20) } } }.width('95%') //设置弹窗宽度 } }}
复制代码

4、HarmonyOS 滑动下一页效果应该如何做?

参考代码:


@Entry@Componentstruct NovelPage {  @Provide('fontSize') @Watch('onFontSizeChange') fontSize: number = Constants.INIT_FONT_SIZE;  @Provide('bgColorIndex') @Watch('onBgColorChanged') bgColorIndex: BGColorType = BGColorType.WHITE;  @Provide('bgColor') bgColor: string = BG_COLOR_ARRAY[BGColorType.WHITE];  @Provide('offsetX') offsetX: number = 0  @Provide('offsetY') offsetY: number = 0;  @Provide('screenH') screenH: number = 0;  @Provide('screenW') screenW: number = 0;  @Provide('sumRow') sumRow: number = 0;  @Provide('rowWord') rowWord: number = 0;  @Provide('rotateAngleOne') rotateAngleOne: number = Constants.INIT_ROTATE_ANGLE_ONE;  @Provide('rotateAngleTwo') rotateAngleTwo: number = 0.0;  @Provide('curPosition') curPosition: number = 0;  @Provide('turnStyle') turnStyle: FlipPageType = FlipPageType.SLIDE_FLIP_PAGE;  @Provide('currentPageNum') @Watch('onFlush') currentPageNum: number = 1;  @Provide('pageWordSum') pageWordSum: number = 0;  @Provide('light') light: number = Constants.INIT_SCREEN_LIGHT;  @Provide('isSystemLight') isSystemLight: boolean = false;  @Provide('rowGap') rowGap: number = Constants.INIT_ROW_GAP;  @State currentStartIndex: number = 0;  @State isShow: boolean = false;  @State isFontChanged: boolean = false;
aboutToAppear(): void { this.screenW = px2vp(display.getDefaultDisplaySync().width); this.screenH = px2vp(display.getDefaultDisplaySync().height - (AppStorage.get('avoidHeight') as number)); this.sumRow = Math.floor((this.screenH) / (this.fontSize + this.rowGap)); this.rowWord = Math.floor((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) / this.fontSize); this.simulatePageContent(); this.changeSystemBarStatue(); }
onFontSizeChange() { this.sumRow = Math.floor((this.screenH) / (this.fontSize + this.rowGap)); this.rowWord = Math.floor((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) / this.fontSize); let pageWordSum = this.sumRow * this.rowWord;
if (this.currentStartIndex > pageWordSum) { this.currentPageNum = Math.floor(this.currentStartIndex / (pageWordSum)) + (this.currentStartIndex > 1 && this.currentStartIndex % pageWordSum > 0 ? 2 : 1); } else if (this.currentStartIndex > 0) { this.currentPageNum = 2; } else { Logger.info('currentStartIndex = ' + this.currentStartIndex); } this.isFontChanged = true; this.simulatePageContent(); }
changeSystemBarStatue(): void { window.getLastWindow(getContext(this), (err, data) => { const errCode = err.code; if (errCode) { return; } let SystemBarProperties: window.SystemBarProperties = { statusBarColor: BG_COLOR_ARRAY[this.bgColorIndex], navigationBarColor: BG_COLOR_ARRAY[this.bgColorIndex], navigationBarContentColor: Constants.TRANSPARENT }; try { data.setWindowSystemBarProperties(SystemBarProperties, (err: BusinessError) => { const errCode: number = err.code; if (errCode) { Logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); return; } data.setWindowBackgroundColor(BG_COLOR_ARRAY[this.bgColorIndex]); }); } catch (exception) { Logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(exception)); } }); }
onBgColorChanged() { this.changeSystemBarStatue(); }
onFlush() { Logger.info('currentPageNum=' + this.currentPageNum + ', isFontChanged=' + this.isFontChanged); if (this.isFontChanged && this.currentPageNum === 1) { this.isFontChanged = false; this.currentStartIndex = 0; } }
simulatePageContent() { this.offsetY = 0; this.rotateAngleTwo = 0.0; this.rotateAngleOne = Constants.INIT_ROTATE_ANGLE_ONE; }
private clickAnimateTo(isLeft: Boolean) { if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) { animateTo({ duration: Constants.SLIDE_DURATION, curve: Curve.EaseOut, onFinish: () => { if (this.offsetX > 0) { this.currentPageNum > 0 ? this.currentPageNum - 1 : this.currentPageNum; this.currentStartIndex -= this.sumRow * this.rowWord; } if (this.offsetX < 0) { this.currentPageNum += 1; this.currentStartIndex += this.sumRow * this.rowWord; } Logger.info(this.currentStartIndex.toString()); this.offsetX = 0; this.simulatePageContent(); } }, () => { if (isLeft) { this.offsetX = this.screenW; } else { this.offsetX = -this.screenW; } }) } }
build() { Row() {
if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) { SlideFlipView({ currentStartIndex: this.currentStartIndex }) }
}
.width(Constants.FULL_PERCENT) .height(Constants.FULL_PERCENT) .bindSheet( $$this.isShow, this.myBuilder(), { height: SheetSize.FIT_CONTENT, detents: [Constants.SHEET_HEIGHT, Constants.SHEET_HEIGHT + 1], showClose: true, dragBar: true, title: { title: Constants.SHEET_TITLE }, backgroundColor: Constants.SHEET_BACKGROUND_COLOR } ) .backgroundColor(this.bgColor) }
@Builder myBuilder() {

}}
@Componentexport default struct Reader { @Consume('bgColor') @Watch('onPageChange') bgColor: string; @Consume('fontSize') @Watch('onPageChange') fontSize: number; @Consume('turnStyle') turnStyle: FlipPageType; @Consume('screenW') screenW: number; @Consume('screenH') screenH: number; @Consume('rowGap') rowGap: number; @Consume('sumRow') sumRow: number @Consume('rowWord') rowWord: number; @Prop @Watch('onPageChange') startIndex: number = 0; private settings: RenderingContextSettings = new RenderingContextSettings(true); private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); private wordWidth: number = 0; private wordHeight: number = 0;
aboutToAppear(): void { this.drawText(this.startIndex); }
onPageChange() { this.drawText(this.startIndex); }
drawText(startIndex: number) { this.wordWidth = this.fontSize; this.wordHeight = this.fontSize; this.context.fillStyle = this.bgColor; this.context.fillRect(0, 0, this.screenW, this.screenH); this.context.fillStyle = Color.Black; this.context.font = vp2px(this.fontSize) + Constants.CANVAS_FONT_SET; if (startIndex < 0) { startIndex = 0; }
let gap = ((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) - this.wordWidth * this.rowWord) / (this.rowWord - 1); let realRowGap = (this.screenH - this.sumRow * (this.wordHeight + this.rowGap)) / (this.sumRow - 1); let currentX = Constants.SCREEN_MARGIN_LEFT; let currentY = this.wordHeight; for (let i = startIndex;; i++) { if (currentX + this.wordWidth > this.screenW - (Constants.SCREEN_MARGIN_LEFT - 1)) { currentX = Constants.SCREEN_MARGIN_LEFT; currentY = currentY + this.rowGap + this.wordHeight + realRowGap; if (currentY > this.screenH) { break; } } this.context.fillText(Constants.TEXT.charAt(i % Constants.TEXT.length), currentX, currentY); currentX += this.wordWidth + gap; } }
build() { Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) { Column() { Canvas(this.context) .width(Constants.FULL_PERCENT) .height(Constants.FULL_PERCENT) .onReady(() => { this.drawText(this.startIndex); }) } .width(Constants.FULL_PERCENT) } .height(Constants.FULL_PERCENT) }}
@Componentexport struct SlideFlipView { @Consume('offsetX') offsetX: number; @Consume('sumRow') sumRow: number; @Consume('rowWord') rowWord: number; @Consume('screenW') screenW: number; @Consume('currentPageNum') currentPageNum: number; @Link currentStartIndex: number; private isFirst: boolean = false;
build() { Stack() { Reader({ startIndex: this.currentStartIndex + this.sumRow * this.rowWord }) .translate({ x: this.offsetX >= 0 ? this.screenW : this.screenW + this.offsetX, y: 0, z: 0 })
Reader({ startIndex: this.currentStartIndex }) .translate({ x: this.offsetX, y: 0, z: 0 }) .width(this.screenW)
Reader({ startIndex: this.currentStartIndex - this.sumRow * this.rowWord }) .translate({ x: this.offsetX >= 0 ? -this.screenW + this.offsetX : -this.screenW, y: 0, z: 0 }) } .gesture( PanGesture() .onActionUpdate((event?: GestureEvent) => { if (!event) { return; } if (this.currentPageNum <= 1 && event.offsetX > 0) { this.isFirst = true; return; }
this.offsetX = event.offsetX; }) .onActionEnd(() => { animateTo({ duration: Constants.FLIP_DURATION, curve: Curve.EaseOut, onFinish: () => { if (this.offsetX > 0) { this.currentPageNum -= 1; if (this.currentStartIndex !== 0) { this.currentStartIndex -= this.sumRow * this.rowWord; } } if (this.offsetX < 0) { this.currentPageNum += 1; this.currentStartIndex += this.sumRow * this.rowWord; } if (this.isFirst) { promptAction.showToast({ message: Constants.MSG_FLIP_OVER, duration: Constants.PROMPT_DURATION }); this.isFirst = false; } this.offsetX = 0; } }, () => { if (this.offsetX > 0) { this.offsetX = this.screenW; } if (this.offsetX < 0) { this.offsetX = -this.screenW; } }) }) ) }}
复制代码

5、HarmonyOS 清除缓存功能?

app 中有清除缓存的需求功能,清除缓存和计算 app 内缓存大小需要怎么实现。


查询缓存用 storageStatistics.getCurrentBundleStats()接口,清除文件缓存,需要调用 context 的 cacheDir 获取缓存,然后调用系统文件 fs 接口,判断是文件或者文件夹,再分别消除缓存https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-file-storage-statistics-V5#storagestatisticsgetcurrentbundlestats9 清理:


import fs from ‘@ohos.file.fs’;let cacheDir = context.cacheDir;@Entry@Componentstruct Clear_cache {  clearCache() {    // let cacheDir = getContext(this).cacheDir    // fs.rmdirSync(cacheDir)    // console.log(“delete !!!”)
fs.listFile(cacheDir).then((filenames) => { for (let i = 0;i < filenames.length; i++) { // let dirPath = cacheDir+filenames[i] let dirPath = ${cacheDir}/${filenames[i]} // 判断是否文件夹 let isDirectory try { isDirectory = fs.statSync(dirPath).isDirectory() } catch (e) { console.log(e) }
if (isDirectory) { fs.rmdirSync(dirPath) } else { fs.unlink(dirPath).then(() => { console.info(“remove file succeed”); }).catch((err) => { console.info("remove file failed with error message: " + err.message + ", error code: " + err.code); }); } }
}) }}
复制代码


发布于: 刚刚阅读数: 4
用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017-10-17 加入

Android、音视频、AI相关领域从业者。 欢迎加我微信wodekouwei拉您进InfoQ音视频沟通群 邮箱:qingkouwei@gmail.com

评论

发布
暂无评论
【每日学点HarmonyOS Next知识】类型判断、刘海高度、隐私弹窗、滑动下一页效果、清楚缓存_HarmonyOS_轻口味_InfoQ写作社区