鸿蒙NEXT问题汇总

打印 上一主题 下一主题

主题 999|帖子 999|积分 2997

鸿蒙NEXT问题汇总

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

关闭分屏

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

沉浸式

  1.       let windowClass = windowStage.getMainWindowSync()
  2.       // 开启沉浸式
  3.       windowClass.setWindowLayoutFullScreen(true)
  4.       // 获取布局避让遮挡的区域
  5.       let avoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
  6.       // 缓存导航条区域的高度
  7.       AppStorage.setOrCreate(CommonConstants.kSafeAreaBottom, px2vp(avoidArea.bottomRect.height));
  8.       avoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
  9.       // 缓存状态栏区域高度
  10.       AppStorage.setOrCreate(CommonConstants.kSafeAreaTop, px2vp(avoidArea.topRect.height));
复制代码
修改状态栏颜色

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

  1.     windowStage.getMainWindow().then(windowClass => {
  2.       this.windowObj = windowClass;
  3.       this.updateWidthBp();
  4.       this.windowObj.on('windowSizeChange', (windowSize: window.Size) => {
  5.         this.updateWidthBp();
  6.       })
  7.     })
  8.   private updateWidthBp(): void {
  9.     if (this.windowObj === undefined) {
  10.       return;
  11.     }
  12.     let mainWindow: window.WindowProperties = this.windowObj.getWindowProperties();
  13.     let windowWidth: number = mainWindow.windowRect.width;
  14.     let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels;
  15.     let widthBp: string = '';
  16.     if ( windowWidthVp < 600) {
  17.       widthBp = 'sm';
  18.     } else if (windowWidthVp >= 600 && windowWidthVp < 840) {
  19.       widthBp = 'md';
  20.     } else {
  21.       widthBp = 'lg';
  22.     }
  23.     AppStorage.setOrCreate('currentWidthBreakpoint', widthBp);
  24.   }
复制代码
键盘避让

RESIZE

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

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

表现模式

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

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

//@formatterff
中心的代码不会格式化
//@formattern
全局

console hilog

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

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

系统预制无返回值block
  1. declare type VoidCallback = () => void;
复制代码
CallBack

系统界说有返回值
  1. declare interface Callback<T, V = void> {
  2.     (data: T): V;
  3. }
复制代码
文件

路径

应用级别

  1. private context = getContext(this) as common.UIAbilityContext;
  2.                 let applicationContext = this.context.getApplicationContext();
  3.         let cacheDir = applicationContext.cacheDir;
  4.         let tempDir = applicationContext.tempDir;
  5.         let filesDir = applicationContext.filesDir;
  6.         let databaseDir = applicationContext.databaseDir;
  7.         let bundleCodeDir = applicationContext.bundleCodeDir;
  8.         let distributedFilesDir = applicationContext.distributedFilesDir;
  9.         let preferencesDir = applicationContext.preferencesDir;
  10.         // 获取应用文件路径
  11.         let filePath = tempDir + 'test.txt';
  12.         hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
  13.         if (filePath !== null) {
  14.           promptAction.showToast({
  15.           message: filePath
  16.           });
  17.         }
复制代码
Hap

  1. private context = getContext(this) as common.UIAbilityContext;
  2.                 let cacheDir = this.context.cacheDir;
  3.         let tempDir = this.context.tempDir;
  4.         let filesDir = this.context.filesDir;
  5.         let databaseDir = this.context.databaseDir;
  6.         let bundleCodeDir = this.context.bundleCodeDir;
  7.         let distributedFilesDir = this.context.distributedFilesDir;
  8.         let preferencesDir = this.context.preferencesDir;
  9.         // 获取应用文件路径
  10.         let filePath = tempDir + 'test.txt';
  11.         hilog.info(DOMAIN_NUMBER, TAG, `filePath: ${filePath}`);
  12.         if (filePath !== null) {
  13.           promptAction.showToast({
  14.             message: filePath
  15.           });
  16.         }
复制代码
加密

应用文件加密是一种保护数据安全的方法,可以使得文件在未经授权访问的情况下得到保护。在差别的场景下,应用必要差别程度的文件保护。
在实际应用中,开发者必要根据差别场景的需求选择合适的加密分区,从而保护应用数据的安全。通过公道使用差别级别的加密分区,可以有效进步应用数据的安全性。关于差别分区的权限分析,详见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/[png|jpeg|bmp|webp];base64,[base64 data]
相机picker

  1.   public openCameraPicker(): Promise<string> {
  2.     const promise: Promise<SelectedPhotoResult> = new Promise(async (resolve: Function, reject: Function) => {
  3.       const pickerResult = await cameraPicker.pick( getContext(), [cameraPicker.PickerMediaType.PHOTO], {
  4.         cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
  5.       })
  6.       if (pickerResult.resultCode === 0 && pickerResult.resultUri.length > 0) {
  7.               resolve(pickerResult.resultUri)
  8.       } else {
  9.               reject()
  10.       }
  11.     })
  12.     return promise
  13.   }
复制代码
Web

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

使用ListItemGroup 实现的上拉加载

  1. // 状态
  2. export enum LoadMoreStatue {
  3.   Normal,
  4.   Puring,
  5.   Loading,
  6.   NetworkError,
  7.   NoMoreData,
  8.   Empty
  9. }
  10. @Component
  11. export struct LoadMoreFooterView {
  12.   @Prop @Watch('statueChanged') statue: LoadMoreStatue = LoadMoreStatue.Normal
  13.   @State private text: string = '上拉加载'
  14.   loadDataAction?: VoidCallback
  15.   build() {
  16.     Column() {
  17.       Row({ space: 10 }) {
  18.         Image($r('app.media.pull_icon_up'))
  19.           .width(20)
  20.           .aspectRatio(1)
  21.           .visibility(this.statue <= LoadMoreStatue.Puring ? Visibility.Visible : Visibility.None)
  22.         LoadingProgress()
  23.           .width(20).aspectRatio(1)
  24.           .visibility(this.statue == LoadMoreStatue.Loading ? Visibility.Visible : Visibility.None)
  25.         Text(this.text)
  26.           .fontColor($r('app.color.color_666'))
  27.           .fontSize(12)
  28.       }
  29.       .justifyContent(FlexAlign.Center)
  30.       .width('100%').height('100%')
  31.     }
  32.     .width('100%').height(40)
  33.     .visibility(this.statue != LoadMoreStatue.Empty ? Visibility.Visible : Visibility.Hidden)
  34.     .onVisibleAreaChange([0.8], (isVisible: boolean, currentRatio: number) => {
  35.       // console.log('isVisible: ' + isVisible, ', currentRatio: ' + currentRatio)
  36.       if (this.statue >= LoadMoreStatue.NoMoreData) {
  37.         return
  38.       }
  39.       if (isVisible && currentRatio >= 0.8) {
  40.         setTimeout(() => {
  41.           this.statue = LoadMoreStatue.Loading
  42.           this.loadDataAction && this.loadDataAction()
  43.         }, 500)
  44.       }
  45.       if (!isVisible) {
  46.         this.statue = LoadMoreStatue.Loading
  47.       }
  48.     })
  49.     .onClick(()=>{
  50.       if (this.statue == LoadMoreStatue.NetworkError) {
  51.         this.loadDataAction && this.loadDataAction()
  52.       }
  53.     })
  54.   }
  55.   statueChanged() {
  56.     switch (this.statue) {
  57.       case LoadMoreStatue.Normal:
  58.       case LoadMoreStatue.Puring:
  59.         this.text = '上拉加载'
  60.         break;
  61.       case LoadMoreStatue.Loading:
  62.         this.text = '正在加载'
  63.         break;
  64.       case LoadMoreStatue.NetworkError:
  65.         this.text = '加载失败,请点击重试'
  66.         break;
  67.       case LoadMoreStatue.NoMoreData:
  68.         this.text = '已加载全部数据'
  69.         break;
  70.       default:
  71.         this.text = ''
  72.     }
  73.   }
  74. }
复制代码
web弹窗

  1.                 Web({            src: this.targetUrl,            controller: this.controller          })                        .mixedMode(MixedMode.All)
  2.             .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企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

民工心事

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表