【每日学点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.ets
    import measure from '@ohos.measure'
    import curves from '@ohos.curves';
    import { BusinessError } from '@ohos.base';
    import display from '@ohos.display';

    @Component
    @Preview
    export 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.ets
    import { MyText } from './MyText'
    @Entry
    @Component
    struct 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
@Component
struct 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)
  }
}

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)
  }
}
相关推荐
SuperHeroWu71 小时前
【HarmonyOS 5】鸿蒙检测系统完整性
华为·harmonyos·模拟器·系统完整性·越狱设备
京东云开发者1 小时前
Taro on Harmony :助力业务高效开发纯血鸿蒙应用
harmonyos
前端付豪2 小时前
2、ArkTS 是什么?鸿蒙最强开发语言语法全讲解(附实操案例)
前端·后端·harmonyos
zhujiaming2 小时前
鸿蒙端应用适配使用开源flutter值得注意的一些问题
前端·flutter·harmonyos
前端付豪2 小时前
8、鸿蒙动画开发实战:做一个会跳舞的按钮!(附动效示意图)
前端·后端·harmonyos
前端付豪2 小时前
3、构建你的第一个鸿蒙组件化 UI 页面:实现可复用的卡片组件(附实战代码)
前端·后端·harmonyos
前端付豪2 小时前
7、打造鸿蒙原生日历组件:自定义 UI + 数据交互(附实操案例与效果图)
前端·后端·harmonyos
北海zx4 小时前
HarmonyNext:如何在鸿蒙上录屏后进行音视频编码
harmonyos
别说我什么都不会4 小时前
【仓颉三方库】音视频开发—— ijkplayer-ffi
harmonyos
王二蛋与他的张大花7 小时前
HarmonyOS运动开发:如何监听用户运动步数数据
harmonyos