【每日学点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)
  }
}
相关推荐
png21 分钟前
从零开始纯血鸿蒙天气预报-主界面(2)
harmonyos·arkui
苏杰豪42 分钟前
鸿蒙特效教程01-哔哩哔哩点赞与一键三连效果实现教程
华为·harmonyos
全栈若城1 小时前
38.HarmonyOS NEXT Layout布局组件系统详解(五):对齐方式设置
harmonyos
全栈若城1 小时前
44.HarmonyOS NEXT Layout布局组件系统详解(十一):最佳实践与高级应用
harmonyos
全栈若城1 小时前
39. HarmonyOS NEXT Layout布局组件系统详解(六):偏移功能实现
harmonyos
是花花呢1 小时前
华为hcia——Datacom实验指南——以太网帧和IPV4数据包格式(二)
运维·服务器·网络·网络协议·华为·华为hcia——datacom
程序漫游人1 小时前
华为欧拉操作系统安装Docker服务
华为·docker·容器
二流小码农2 小时前
鸿蒙开发:实现AI打字机效果
android·ios·harmonyos
万少2 小时前
01-万少带你精读鸿蒙 codelabs 一多界面适配和三层架构
前端·harmonyos
程序猿阿伟2 小时前
《深度剖析:鸿蒙系统下智能NPC与游戏剧情的深度融合》
游戏·华为·harmonyos