写点什么

【每日学点 HarmonyOS Next 知识】顶部状态栏、文本最大行数后缀、弹窗背景、状态栏颜色、导航

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

    阅读完需:约 21 分钟

【每日学点HarmonyOS Next知识】顶部状态栏、文本最大行数后缀、弹窗背景、状态栏颜色、导航

1、HarmonyOS 应用把顶部系统状态栏信息完全覆盖了?

//设置窗口全屏模式时导航栏、状态栏的可见模式(需全部显示,该参数设置为['status', 'navigation'],不设置,则默认不显示)let names: Array<'status' | 'navigation'> = [];windowClass.setWindowSystemBarEnable(names, (err: BusinessError) => {  let errCode: number = err.code;  if (errCode) {    console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err));    return;  }  console.info('Succeeded in setting the system bar to be visible.');});console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
复制代码


参考文档:https://developer.huawei.com/consumer/cn/doc/app/50106设置全屏沉浸式后可以使用 getWindowAvoidArea()接口获取布局遮挡区域,在组件中根据避让区域返回值自行设置:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-develop-apply-immersive-effects-V5如果需要显示状态栏和导航栏的话,是要每个页面都去做规避的,如果可以不想显示状态和导航栏可以通过 setSpecificSystemBarEnabled 来隐藏:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5关于窗口内容需要规避区域的类型枚举:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5

2、HarmonyOS 怎么处理文本显示最大行数后 追加...全文的问题?

用计算的方式算出每个字的宽度,累加,但是有时计算不准确,我们文字内部含有表情,然后有时系统一些文字也会折行,用了 wordBreak(WordBreak.BREAK_ALL)这个 api 不折行显示了,但是还是计算不准确,延后显示。


  1. 首先使用 measure.measureText()方法测量实际文本宽度,接着使用 display.getAllDisplays()获取手机屏幕宽度,然后用“屏幕宽度 * 最大行数 * 组件宽度比例”的结果和“实际文本宽度”进行比较大小,判断是否需要“…展开全文”;

  2. 当需要“…展开全文”时,只展示 maxLines 属性设置的固定高度的文本内容,当点击“…展开全文”时将该文本改成“…收起”并添加 curves.springMotion 曲线动画,同时在 animateTo 的显示动效的闭包函数中将 maxLines 属性值修改为-1 使得该属性无效;

  3. 当需要“…收起”时,将 collapseText 的值改为“…展开全文”,并设置收起动画。


// MyText.etsimport measure from '@ohos.measure'import curves from '@ohos.curves';import { BusinessError } from '@ohos.base';import display from '@ohos.display';
@Component@Previewexport struct MyText { // 长文本 @State longMessage: string = "ArkTS提供了简洁自然的声明式语法、组件化机制、数据-UI自动关联等能力,实现了贴近自然语言,书写效率更高的编程方式,为开发者带来易学、易懂、简洁开发的优质体验。" // 最大显示行数 @State lines: number = 3; // 长文本状态(展开 or 收起) @State collapseText: string = '...展开全文' // 屏幕宽度(单位px) screenWidth: number = 0; // 是否需要显示"展开"字样(注:当文本长度较短时就不需要“展开”) @State isExpanded: boolean = false // 测量文本宽度(单位px) @State textWidth: number = measure.measureText({ textContent: this.longMessage, fontSize: 15 }) // 获取当前所有的display对象 promise: Promise<Array<display.Display>> = display.getAllDisplays()
aboutToAppear() { console.log(`文本宽度为:${this.textWidth}`) this.promise.then((data: Array<display.Display>) => { console.log(`所有的屏幕信息:${JSON.stringify(data)}`) //单位为像素 this.screenWidth = data[0]["width"] // 屏幕宽度 * 最大行数 * 组件宽度比例 和 文字测量宽度 this.isExpanded = this.screenWidth * this.lines * 0.8 <= this.textWidth }).catch((err: BusinessError) => { console.error(`Failed to obtain all the display objects. Code: ${JSON.stringify(err)}`) }) }
build() { Row() { Column() { if (this.isExpanded) { Stack({ alignContent: Alignment.BottomEnd }) { Text(this.longMessage) .fontSize(15) .fontColor(Color.Black) .maxLines(this.lines) .width('80%') Row() { Text(this.collapseText) .fontSize(15) .backgroundColor(Color.White) } .justifyContent(FlexAlign.End) .onClick(() => { if (this.collapseText == '...展开全文') { this.collapseText = '...收起'; // 展开动画 animateTo({ duration: 150, curve: curves.springMotion(0.5, 0.8), }, () => { this.lines = -1; // 使得设置的最大行属性无效 }) } else { this.collapseText = '...展开全文'; // 收起动画 animateTo({ duration: 100, curve: Curve.Friction, }, () => { this.lines = 3; // 只显示3行 }) } }) } } else { Text(this.longMessage) .fontSize(15) .fontColor(Color.Black) } } .width('100%') } .height('100%') }}

// Index.etsimport { MyText } from './MyText'@Entry@Componentstruct Index { build(){ Column(){ MyText() } }}
复制代码

3、HarmonyOS 组件绑定 popup 弹窗,如何将弹窗背景设置成透明状态?

popupColor 设置成透明但弹窗还是默认白色背景


Image($r("app.media.gray_tips_icon"))  .width($r("app.string.dp15"))  .height($r("app.string.dp15"))  .onClick(() => {    this.tipPopup = !this.tipPopup  })  .bindPopup(this.tipPopup, {    builder: this.popupBuilder(),    placement: Placement.Top,    mask: false,    popupColor: Color.Transparent,    enableArrow: true,    showInSubWindow: false,    onStateChange: (e) => {      if (!e.isVisible) {        this.tipPopup = false      }    },    arrowOffset: $r("app.string.dp50"),    offset: { x: $r("app.string.dp20") },    radius: $r("app.string.dp8")  })
复制代码


参考代码:


@Entry@Componentstruct PopupExample {  @State handlePopup: boolean = false  @Builder popupBuilder(){    Text('气泡的内容')  }
build() { Column() { Button('PopupOptions') .onClick(() => { this.handlePopup = !this.handlePopup }) .bindPopup(this.handlePopup, { builder: this.popupBuilder(),//内容 placement:Placement.Bottom, // 气泡的弹出位置 maskColor: Color.Transparent, popupColor:Color.Transparent, // 气泡的背景色 backgroundBlurStyle: BlurStyle.NONE, shadow: { radius:0 }, onStateChange: (e) => { console.info(JSON.stringify(e.isVisible)) if (!e.isVisible) { this.handlePopup = false } } }) } .justifyContent(FlexAlign.Center) .height('100%') .width('100%') .padding({ top: 5 }) .backgroundColor(Color.Pink) }}
复制代码

4、HarmonyOS Navigation 组件 hideNavBar 问题?

Navigation 组件设置.hideNavBar(true),调用 pushPathByName 打开首页和二级页面首页的 navBar 隐藏,符合预期二级页面的 navBar 未隐藏且有返回按钮,有办法隐藏吗


设置 NavDestination().hideTitleBar(true)

5、HarmonyOS 每个页面状态栏背景颜色和字体颜色不一样,怎么动态设置每个页面的沉浸式状态栏?

目前尝试在每个页面生命周期 onPageShow 和 aboutToApear 中调用以上两个方法,但是有些页面颜色还是没变过来,出现了问题,生命周期中无法正确改变系统状态栏颜色


参考代码:


修改了一下代码参考:import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';import { hilog } from '@kit.PerformanceAnalysisKit';import { window } from '@kit.ArkUI';import { WindowManager } from '../WindowManager';
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'); }
onWindowStageCreate(windowStage: window.WindowStage) { hilog.info(0x0000, 'testTag', JSON.stringify(this.context), 'context-tag');
// Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('enablement/enablement', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; }
let windowClass = windowStage.getMainWindowSync(); AppStorage.setOrCreate('windowClass', windowClass);
WindowManager.enableFullScreen() hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); // let windowClass: window.Window = windowStage.getMainWindowSync(); //获取应用主窗口 // windowClass.setWindowLayoutFullScreen(true) // let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; //以导航条避让为例 // let avoidArea = windowClass.getWindowAvoidArea(type); // let bottomRectHeight = px2vp(avoidArea.bottomRect.height); //获取到导航条区域的高度 // AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight) //将高度转成vp,存到AppStorage中方便其它页面获取高度 // let area = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); // let statusBarHeight = px2vp(area.topRect.height) //状态栏高度 // AppStorage.setOrCreate('statusBarHeight', statusBarHeight) //将高度转成vp,存到AppStorage中方便其它页面获取高度 // hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); // windowClass.setWindowSystemBarEnable(['status', 'navigation']) // windowClass.setWindowSystemBarProperties({ // statusBarColor: "#FFFFFF", // statusBarContentColor: '#FFFFFF' // })
}); }
onWindowStageDestroy(): void { // Main window is destroyed, release UI related resources hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); }
onForeground(): void { // Ability has brought to foreground hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); }
onBackground(): void { // Ability has back to background hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); }}
//WindowManager.ets
import{ window}from'@kit.ArkUI';import { BusinessError } from '@kit.BasicServicesKit';import { LogUtil } from '@pura/harmony-utils';

// 设置沉浸式工具类export class WindowManager { private static readonly TAG: string = "WindowManager---"
//开启沉浸式全屏模式 static enableFullScreen() { let win: window.Window = AppStorage.get('windowClass')! win.setWindowLayoutFullScreen(true) //使用setWindowLayoutFullScreen设置true开启沉浸式模式 const topArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM) //使用getWindowAvoidArea方法获取到安全区域的高度 let topHeight = px2vp(topArea.topRect.height) AppStorage.setOrCreate('topHeight', topHeight) //将高度转成vp,存到AppStorage中方便其它页面获取高度 const bottomArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) let bottomHeight = px2vp(bottomArea.bottomRect.height) AppStorage.setOrCreate('bottomHeight', bottomHeight) //将高度转成vp,存到AppStorage中方便其它页面获取高度 LogUtil.error(WindowManager.TAG, `topHeight:${topHeight},,,bottomHeight:${bottomHeight}`) }
//关闭沉浸式模式 static disableFullScreen() { let win: window.Window = AppStorage.get('windowClass')! win.setWindowLayoutFullScreen(false) //使用setWindowLayoutFullScreen设置false关闭沉浸式模式 AppStorage.setOrCreate('topHeight', 0) //将高度重置为零 }
static settingStatusBarLight() { let win: window.Window = AppStorage.get('windowClass')! win.setWindowSystemBarProperties({ statusBarContentColor: '#FFFFFF' }) //设置安全区字体颜色为白色
}
static settingStatusBarDark() { let win: window.Window = AppStorage.get('windowClass')! win.setWindowSystemBarProperties({ statusBarContentColor: '#000000' }) //设置安全区字体颜色为黑色 }
static async keepScreenOn(isKeepScreenOn: boolean) { let win: window.Window = AppStorage.get('windowClass')! let promise = win.setWindowKeepScreenOn(isKeepScreenOn) promise?.then(() => { LogUtil.error(WindowManager.TAG, `${isKeepScreenOn ? "打开" : "关闭"}屏幕常亮成功`) }).catch((error: BusinessError) => { LogUtil.error(WindowManager.TAG, `${isKeepScreenOn ? "打开" : "关闭"}屏幕常亮异常,error:${JSON.stringify(error)}`) });
}
private static async setWindowBrightness(brightness: number) { let win: window.Window = AppStorage.get('windowClass')!
let promise = win.setWindowBrightness(brightness) promise?.then(() => { LogUtil.error(WindowManager.TAG, "设置屏幕亮度成功") }).catch((error: BusinessError) => { LogUtil.error(WindowManager.TAG, "设置屏幕亮度异常,error:" + JSON.stringify(error)) });
}
static setWindowMaxBrightness() { WindowManager.setWindowBrightness(1) }
static setWindowDefaultBrightness() { WindowManager.setWindowBrightness(-1) }}
复制代码


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

轻口味

关注

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

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

评论

发布
暂无评论
【每日学点HarmonyOS Next知识】顶部状态栏、文本最大行数后缀、弹窗背景、状态栏颜色、导航_HarmonyOS_轻口味_InfoQ写作社区