民工心事 发表于 2024-12-22 08:19:30

鸿蒙NEXT问题汇总

鸿蒙NEXT问题汇总


本文作为本人在开发过程中遇到的一些不涉及保密的问题,记载并盼望能资助他人。
作为已经入坑的鸿蒙开发者,建议初学者直接使用华为开发者文档学习,目前已经开放,不像之前只对开发者开放。
不要信赖第三方机构所谓的“源码”,他们都是从华为官网下载的,华为有提供详细的指南、api、demo等
工程

关闭分屏

鸿蒙默认是 全屏、窗口、分屏,修改为全屏就不支持 分屏等,可以不适配
Entry module.json5 abilities 增长 supportWindowMode
    "abilities": [
      {
      "name": "EntryAbility",
      "supportWindowMode": ["fullscreen"]
      }
    ],
EntryAbility

沉浸式

      let windowClass = windowStage.getMainWindowSync()

      // 开启沉浸式
      windowClass.setWindowLayoutFullScreen(true)

      // 获取布局避让遮挡的区域
      let avoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
      // 缓存导航条区域的高度
      AppStorage.setOrCreate(CommonConstants.kSafeAreaBottom, px2vp(avoidArea.bottomRect.height));

      avoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
      // 缓存状态栏区域高度
      AppStorage.setOrCreate(CommonConstants.kSafeAreaTop, px2vp(avoidArea.topRect.height));
修改状态栏颜色

      let sysBarProps: window.SystemBarProperties = {
      statusBarColor: '#55FF3300',
      // statusBarContentColor: '#FFFFFF'
      };
      // 2.设置窗口内导航栏、状态栏属性。systemBarProperties:导航栏、状态栏的属性集合
      windowClass.setWindowSystemBarProperties(sysBarProps)
一多break point

    windowStage.getMainWindow().then(windowClass => {
      this.windowObj = windowClass;
      this.updateWidthBp();
      this.windowObj.on('windowSizeChange', (windowSize: window.Size) => {
      this.updateWidthBp();
      })
    })

private updateWidthBp(): void {
    if (this.windowObj === undefined) {
      return;
    }
    let mainWindow: window.WindowProperties = this.windowObj.getWindowProperties();
    let windowWidth: number = mainWindow.windowRect.width;
    let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels;
    let widthBp: string = '';
    if ( windowWidthVp < 600) {
      widthBp = 'sm';
    } else if (windowWidthVp >= 600 && windowWidthVp < 840) {
      widthBp = 'md';
    } else {
      widthBp = 'lg';
    }
    AppStorage.setOrCreate('currentWidthBreakpoint', widthBp);
}
键盘避让

RESIZE

resize 默认会缩小屏幕高度以表现键盘,包罗tabbar等都会上移,不符合需求
OFFSET

offset默认会将页面内容上移,同样不符合需求
正常做法是设置OFFSET(默认),然后将保护Input的页面(非input组件)
增长扩展地区
.expandSafeArea()
windowClass.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE);
windowClass.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.OFFSET);
DevEco

表现模式

可以切换为 Ohos 模式,可以简化目次,忽略暂时文件,视觉更清楚
应用包名要求

必须为以点号(.)分隔的字符串,且至少包含三段,每段中仅允许使用英笔墨母、数字、下划线(_),如“com.example.myapplication ”。
首段以英笔墨母开头,非首段以数字或英笔墨母开头,每一段以数字大概英笔墨母末端,如“com.01example.myapplication”。
不允许多个点号(.)连续出现,如“com.example…myapplication ”。
长度为7~128个字符。
忽略格式化

//@formatter:off
中心的代码不会格式化
//@formatter:on
全局

console hilog

输出长度均为 4096 超长截断,目前只能分段输出
国难日 全局置灰

首页置灰
根组件Tabs添加 .grayscale(1)
如果必要二级页置灰,则每个页面根都必要添加 .grayscale(1)
VoidCallback

系统预制无返回值block
declare type VoidCallback = () => void;
CallBack

系统界说有返回值
declare interface Callback<T, V = void> {
    (data: T): V;
}
文件

路径

应用级别

private context = getContext(this) as common.UIAbilityContext;

                let applicationContext = this.context.getApplicationContext();
      let cacheDir = applicationContext.cacheDir;
      let tempDir = applicationContext.tempDir;
      let filesDir = applicationContext.filesDir;
      let databaseDir = applicationContext.databaseDir;
      let bundleCodeDir = applicationContext.bundleCodeDir;
      let distributedFilesDir = applicationContext.distributedFilesDir;
      let preferencesDir = applicationContext.preferencesDir;
      // 获取应用文件路径
      let filePath = tempDir + 'test.txt';
      hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
      if (filePath !== null) {
          promptAction.showToast({
          message: filePath
          });
      }
Hap

private context = getContext(this) as common.UIAbilityContext;

                let cacheDir = this.context.cacheDir;
      let tempDir = this.context.tempDir;
      let filesDir = this.context.filesDir;
      let databaseDir = this.context.databaseDir;
      let bundleCodeDir = this.context.bundleCodeDir;
      let distributedFilesDir = this.context.distributedFilesDir;
      let preferencesDir = this.context.preferencesDir;
      // 获取应用文件路径
      let filePath = tempDir + 'test.txt';
      hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
      if (filePath !== null) {
          promptAction.showToast({
            message: filePath
          });
      }
加密

应用文件加密是一种保护数据安全的方法,可以使得文件在未经授权访问的情况下得到保护。在差别的场景下,应用必要差别程度的文件保护。
在实际应用中,开发者必要根据差别场景的需求选择合适的加密分区,从而保护应用数据的安全。通过公道使用差别级别的加密分区,可以有效进步应用数据的安全性。关于差别分区的权限分析,详见ContextConstant的AreaMode。


[*]EL1:对于私有文件,如闹铃、壁纸等,应用可以将这些文件放到装备级加密分区(EL1)中,以保证在用户输入密码前就可以被访问。
[*]EL2:对于更敏感的文件,如个人隐私信息等,应用可以将这些文件放到更高级别的加密分区(EL2)中,以保证更高的安全性。
[*]EL3:对于应用中的记载步数、文件下载、音乐播放,必要在锁屏时读写和创建新文件,放在(EL3)的加密分区比力合适。
[*]EL4:对于用户安全信息相关的文件,锁屏时不必要读写文件、也不能创建文件,放在(EL4)的加密分区更合适。
Component

TextInput

ebnable

设置为 false 时无法修改文本颜色
Image

图片加载

Image 可表现 当地资源、网络资源、Resource资源、媒体库资源和base64
当地资源

创建文件夹,将当地图片放入ets文件夹下的任意位置。
Image组件引入当地图片路径,即可表现图片(根目次为ets文件夹)
http

可直接加载网络资源
Resource



[*]media
[*]rawfile
媒体库 uri

uri为picker等获取的uri (uir为只读,如果相册删除后,图片应该获取不到,建议使用base64,而且方便长期化缓存)
base64

路径格式为 data:image/;base64,
相机picker

public openCameraPicker(): Promise<string> {
    const promise: Promise<SelectedPhotoResult> = new Promise(async (resolve: Function, reject: Function) => {

      const pickerResult = await cameraPicker.pick( getContext(), , {
      cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
      })
      if (pickerResult.resultCode === 0 && pickerResult.resultUri.length > 0) {
              resolve(pickerResult.resultUri)
      } else {
              reject()
      }
    })
    return promise
}
Web

web表现完全,不滚动,用于弹窗大概详情页混排的情况
.mixedMode(MixedMode.All)
Code

使用ListItemGroup 实现的上拉加载

// 状态
export enum LoadMoreStatue {
Normal,
Puring,
Loading,
NetworkError,
NoMoreData,
Empty
}

@Component
export struct LoadMoreFooterView {
@Prop @Watch('statueChanged') statue: LoadMoreStatue = LoadMoreStatue.Normal
@State private text: string = '上拉加载'
loadDataAction?: VoidCallback

build() {
    Column() {
      Row({ space: 10 }) {
      Image($r('app.media.pull_icon_up'))
          .width(20)
          .aspectRatio(1)
          .visibility(this.statue <= LoadMoreStatue.Puring ? Visibility.Visible : Visibility.None)
      LoadingProgress()
          .width(20).aspectRatio(1)
          .visibility(this.statue == LoadMoreStatue.Loading ? Visibility.Visible : Visibility.None)

      Text(this.text)
          .fontColor($r('app.color.color_666'))
          .fontSize(12)
      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
    }
    .width('100%').height(40)
    .visibility(this.statue != LoadMoreStatue.Empty ? Visibility.Visible : Visibility.Hidden)
    .onVisibleAreaChange(, (isVisible: boolean, currentRatio: number) => {
      // console.log('isVisible: ' + isVisible, ', currentRatio: ' + currentRatio)
      if (this.statue >= LoadMoreStatue.NoMoreData) {
      return
      }
      if (isVisible && currentRatio >= 0.8) {
      setTimeout(() => {
          this.statue = LoadMoreStatue.Loading
          this.loadDataAction && this.loadDataAction()
      }, 500)
      }

      if (!isVisible) {
      this.statue = LoadMoreStatue.Loading
      }
    })
    .onClick(()=>{
      if (this.statue == LoadMoreStatue.NetworkError) {
      this.loadDataAction && this.loadDataAction()
      }
    })
}

statueChanged() {
    switch (this.statue) {
      case LoadMoreStatue.Normal:
      case LoadMoreStatue.Puring:
      this.text = '上拉加载'
      break;
      case LoadMoreStatue.Loading:
      this.text = '正在加载'
      break;
      case LoadMoreStatue.NetworkError:
      this.text = '加载失败,请点击重试'
      break;
      case LoadMoreStatue.NoMoreData:
      this.text = '已加载全部数据'
      break;
      default:
      this.text = ''
    }
}
}
web弹窗

                Web({            src: this.targetUrl,            controller: this.controller          })                        .mixedMode(MixedMode.All)
            .height('30%')            .constraintSize({            maxHeight: '100%'            })            .layoutMode(WebLayoutMode.FIT_CONTENT)            .backgroundColor(this.isLoading ? '#00000000' : '#FFFFFF')            .onPageEnd(() => {            this.isLoading = false            })            .onErrorReceive((event) => {            this.isLoading = false            }) 常用认识

clip

constraintSize

三方

PullToRefresh

重点必要关闭回弹,使用的panGest,目前已知无法设置加载失败及没有更多的状态
List().edgeEffect(EdgeEffect.None)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙NEXT问题汇总