写点什么

【每日学点 HarmonyOS Next 知识】防截屏、加载不同 View、函数传参、加载中效果、沉浸式底部状态栏

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

    阅读完需:约 13 分钟

【每日学点HarmonyOS Next知识】防截屏、加载不同View、函数传参、加载中效果、沉浸式底部状态栏

1、HarmonyOS 如何在一个 push 的子页面中实现防截屏功能?

1、用户点击登录后,Navigation.push 到登录页 2、如何在登录页中实现防截屏功能,并在退出登录页时,取消防截屏功能


可以在登录页回调中设置主窗口为隐私模式,在登陆页的 aboutToAppear 周期设置为隐私模式,当退出页面时,再退出隐私模式即可,详情请参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs-V5/faqs-arkui-3-V5


setWindowPrivacyMode 设置窗口是否为隐私模式,设置为隐私模式的窗口,窗口内容将无法被截屏或录屏。此接口可用于禁止截屏/录屏的场景。


在 onWindowStageCreate 回调中设置主窗口为隐私模式,具体可参考示例代码:


import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; onWindowStageCreate(windowStage: window.WindowStage): void {     // Main window is created, set main page for this ability     hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');     // 获取主窗口     windowStage.getMainWindow((err: BusinessError, data) => {       let errCode: number = err.code;       if (errCode) {         console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));         return;       }       let windowClass: window.Window = data;       console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));       // 设置窗口隐私模式       let isPrivacyMode: boolean = true;       try {         windowClass.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) => {           const errCode: number = err.code;           if (errCode) {             console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(err));             return;           }           console.info('Succeeded in setting the window to privacy mode.');         });       } catch (exception) {         console.error('Failed to set the window to privacy mode. Cause:' + JSON.stringify(exception));       }     })     windowStage.loadContent('pages/Index', (err, data) => {       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. Data: %{public}s', JSON.stringify(data) ?? '');     });   }
复制代码

2、HarmonyOS 如何在一个 page 里面,然后通过点击一个按钮,显示加载不同的 view?

参考代码:


import { BusinessError } from "@ohos.base";import { HashMap } from '@kit.ArkTS';import map from '@hms.core.map.map';
@Componentstruct Child { @Builder customBuilder() { }
// 使用父组件@Builder装饰的方法初始化子组件@BuilderParam @BuilderParam customBuilderParam: () => void = this.customBuilder;
build() { Column() { this.customBuilderParam()
} }}
@Entry@Componentstruct Index45 { @State message: string = 'Hello World'; @State keys: number = 1
@Builder component1() { Column() { Text('component0') .width(100) .backgroundColor(Color.Red) } .width('100%') }
@Builder component2() { Column() { Text('component1') .width(100) .backgroundColor(Color.Red) } .width('100%') }
@Builder component3() { Column() { Text('component2') .width(100) .backgroundColor(Color.Red) } .width('100%') }
build() {
Column({ space: 30 }) { Text('显示component1') .fontSize(20) .fontWeight(FontWeight.Bold) .onClick(() => { this.keys = 0 }) Text('显示component2') .fontSize(20) .fontWeight(FontWeight.Bold) .onClick(() => { this.keys = 1 }) Text('显示component3') .fontSize(20) .fontWeight(FontWeight.Bold) .onClick(() => { this.keys = 2
})
if (this.keys === 0) { Child({ customBuilderParam: this.component1 }) } else if (this.keys === 1) { Child({ customBuilderParam: this.component2 }) } else { Child({ customBuilderParam: this.component3 }) } } .height('100%') .width('100%') }}
复制代码

3、HarmonyOS 函数传参:function 应该用什么类接收?

函数传参:function 应该用什么类接收


定义方法可以参考以下代码:get(url:string,callback:()=>void) { }

4、HarmonyOS showLoading 和 showToast 怎么实现?

可使用 promptAction.openCustomDialog 自定义弹窗:


//Index.ets import {  changeDialogBuilder,  MyShowTest}  from '../common/HttpUtils'import {  customDialogBuilder}  from './testProm'let myShowTest = new MyShowTest()@Entry@Component struct Index {@State message: string = 'Hello World'onPageShow() : void {  changeDialogBuilder(customDialogBuilder.bind(this))}  build() {    Row() {      Column() {        Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).onClick(() = >{          myShowTest.showTest()        })      }.width('100%')    }.height('100%')  }}//testProm.ets @Builder exportfunction customDialogBuilder() {  Column() {    Text('正在加载中').fontSize(16)  }.height(100).width(100).backgroundColor('#EEE')}//HttpUtils.ets import promptAction from '@ohos.promptAction'let myDialogBuilder: CustomBuilder;let customDialogId: number = 0 exportfunction changeDialogBuilder(builder: CustomBuilder) {  myDialogBuilder = builder}export class MyShowTest {  showTest() {    if (myDialogBuilder === undefined) {      return    }    promptAction.openCustomDialog({      builder: myDialogBuilder,      alignment: DialogAlignment.Center,    }).then((dialogId: number) = >{      customDialogId = dialogId    }) setTimeout(() = >{      promptAction.closeCustomDialog(customDialogId)    },      2000)  }}
复制代码

5、HarmonyOS 沉浸式设置底部状态栏高度变化问题?

在页面中设置全屏和 js 中设置全屏效果不一致


window.getLastWindow(getContext()).then((win) => {  win.setWindowLayoutFullScreen(true)})
复制代码


可参考 demo


import { window } from '@kit.ArkUI'
@Entry@Componentexport struct ExpandSafeArea2 { @State currentIndex: number = 0 @State isFullScreen: boolean = false @State curWindow: window.Window | undefined = undefined @State TabArr: string[] = ['首页', '推荐', '发现', '我的'] @State statusArr: boolean[] = [] private bottomRectHeight: number = 0 @State marginBottom: number = 0
aboutToAppear(): void { //这里更新statusArr数据,实际上在加载h5的时候获取 this.statusArr = [true, true, false, false] window.getLastWindow(getContext()).then((win) => { this.curWindow = win; // 根据status信息判断首个界面是否设置沉浸式 this.curWindow.setWindowLayoutFullScreen(true) let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例 let avoidArea = win.getWindowAvoidArea(type); console.log(JSON.stringify(avoidArea.bottomRect)) this.bottomRectHeight = px2vp(avoidArea.bottomRect.height); // 获取到导航条区域的高度 this.handleFullScreen(this.currentIndex) }) }
handleFullScreen(index: number) { if (!this.curWindow || !this.statusArr.length) { return; } // 对应tab的逻辑 this.curWindow.setWindowLayoutFullScreen(this.statusArr[index]) this.marginBottom = this.statusArr[index] === true ? this.bottomRectHeight : 0 // 沉浸式的时候添加底部margin }
@Builder tabBuilder(title: string, targetIndex: number) { Column() { Text(title) .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') } .width('100%') .height(50) .justifyContent(FlexAlign.Center) }
build() { Column() { Tabs({ barPosition: BarPosition.End }) { ForEach(this.TabArr, (tab: string, index: number) => { TabContent() { Text(tab + '沉浸状态:' + this.statusArr[index]).fontSize(30) } .backgroundColor(Color.Red) .tabBar(this.tabBuilder(tab, 0)) .onWillShow(() => { this.handleFullScreen(index) }) }) } .vertical(false) .clip(false) //tabs包含的时候需要注意, clip默认是开启的。需要关闭不然子节点不能扩展安全区域。 .width('100%') .height('100%') .onChange((index: number) => { this.currentIndex = index }) } .margin({ bottom: this.marginBottom }) }}
复制代码


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

轻口味

关注

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

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

评论

发布
暂无评论
【每日学点HarmonyOS Next知识】防截屏、加载不同View、函数传参、加载中效果、沉浸式底部状态栏_HarmonyOS_轻口味_InfoQ写作社区