《鸿蒙纪元》 是 张风捷特烈[1] 计划打造的一套 HarmonyOS 开发系列教程合集。 致力于创作优质的鸿蒙原生学习资源,帮助开发者进入纯血鸿蒙的开发之中。 本系列的所有代码将开源在 HarmonyUnit[2] 项目中:
github: https://github.com/toly1994328/HarmonyUnit gitee: https://gitee.com/toly1994328/HarmonyUnit 本文是《鸿蒙纪·梦始卷》 的第三章,上一篇我们搭建了一个简单的功能应用,本篇将基于这个小案例,继续优化界面表现。本文你将学到: [1]. 学会资源文件的使用,包括图片、字符串、颜色、数字等。 [2]. 学会沉浸状态导航栏,实现全屏布局的方案。 [3]. 了解鸿蒙开发时文字、视图尺寸单位,统一配置常量资源。
资源文件在 entry/src/main/resources 文件夹下: 官方文档中对资源目录结构[3]有详细的介绍,目前我们主要使用 base 的 media 文件夹中放置媒体数据,比如图片、音频;在 element 文件夹中放置字符串、颜色等常量资源。
1. 图片文件的使用 ArkUI 中通过 Image 组件展示图片,它可以支持常规的图片格式,比如 png、jpg、webp、gif 等,也可以直接支持 svg 的图像资源:。如下所示,将 logo.webp 和 more.svg 放到 media 文件夹下: 现在,我们的目标是将这两个图片资源放置在计数器 AppBar 的两侧,如下所示:
上一篇中,我们通过插槽的方式,将 AppBar 左右组件交由外部传入,想要更改左侧展示内容,只需要在 Index 组件的 leading 构建方法中修改即可: 这里通过 Button 组件占据 36*36 的尺寸,内部放置 Image 组件,尺寸是 30*30;media 中的图片资源通过 $r('app.media.名称') 来访问:
---->[Index.ets#Index]---- @Builder leading() { Button(){ Image($r('app.media.logo' )).width(30 ).height(30 ) } .width(36 ).height(36 ) .backgroundColor(Color.Transparent)
}
同理,AppBar 尾部的组件可以通过修改 tailing 组件进行构建;另外 svg 图片可以通过 fillColor 修改颜色值,这相比于普通图片更加灵活: @Builder tailing() { Button(){ Image($r('app.media.more' )) .width(24 ).height(24 ) .fillColor(Color.White) } .width(36 ).height(36 ) .backgroundColor(Color.Transparent) }
2.常量数值资源 对于一些全局的常量资源,我们可以统一配置在资源中,方便统一维护,比如字体大小、颜色、字符串等。防止在 element 文件夹下,其中: 比如计数器中,按钮颜色、AppBAr 颜色都是一样的,我们想要定义一个主题色,方便统一维护。可以在 color.json 中增加一个 theme_color 的元素,指定对应的值, 在代码中通过 $r 访问资源设置即可。
{ "color" : [ { "name" : "start_window_background" , "value" : "#FFFFFF" }, { "name" : "theme_color" , "value" : "#317bd4" } ] }
这样,color 中的 theme_color 修改后,就可以让所有使用到它的地方发生变化: 3. 了解像素单位 对于需要统一维护尺寸、字符串,字符串和数值的资源也是同理。比如文字大小、边距间隔值、应用名称等。这里简单介绍一下像素相关的单位。如下四个分别是使用 18px、18vp、 18数字、18sp 设置文字大小的效果: 我们知道屏幕是由一个个像素点构成的, px 单位就是绝对的像素数字。 fp 表示 虚拟像素 (virtual pixel) 是一台设备针对应用而言所具有的虚拟尺寸, 它可在任何屏幕上缩放以具有统一的尺寸体量。从二三两行可以看出,在代码中,数值本身就是虚拟像素值。
fp 表示 字体像素 (font pixel) 默认情况下与 vp 相同,即默认情况下 1 fp = 1vp。所以三四行表现效果相同。但如果用户在设置中选择了更大的字体,字体的实际显示大小就会在 vp 的基础上乘以 scale 系数,即 1 fp = 1 vp * scale。所以对于文字来说,一般取用 fp 单位,其他尺寸可以直接使用数值。
Text ('鸿蒙纪元 HarmonyUnit: 18px').fontSize('18px') Text ('鸿蒙纪元 HarmonyUnit: 18vp').fontSize('18vp') Text ('鸿蒙纪元 HarmonyUnit: 18').fontSize(18) Text ('鸿蒙纪元 HarmonyUnit: 18fp').fontSize('18fp')
通过 $r('app.float.xxx') 可以访问资源中提供的尺寸值,如下所示为计数器的描述和数值,设置文字大小:
{ "float" : [ { "name" : "counter_value_size" , "value" : "36fp" }, { "name" : "counter_desc_size" , "value" : "18fp" }, { "name" : "app_bar_title_size" , "value" : "20fp" } ]
}
对于这种数值资源,IDE 也会自动展示对应的数值,也保证一定的代码可读性: 4. 国际化资源配置 一般应用程序中展示的资源字符串需要适应系统中不同的语言,鸿蒙开发中提供了资源字符串国际化的方案。在项目中有对应语言的文件夹,在其中的 string.json 中定义映射关系,就可以支持国际化。 ---->[src/main/resources/base /string .json]---- { "name" : "counter_title" , "value" : "计数器" }, { "name" : "counter_tips" , "value" : "下面是你点击按钮的次数:" } ---->[src/main/resources/en_US/element/string .json]---- { "name" : "counter_title" , "value" : "Counter" }, { "name" : "counter_tips" , "value" : "You have pushed the button this many times:" } ---->[src/main/resources/zh_CN/element/string .json]---- { "name" : "counter_title" , "value" : "计数器" }, { "name" : "counter_tips" , "value" : "下面是你点击按钮的次数:"
}
如下所示,如果希望在 系统语言 切换时,应用程序可以展示不同的字符串资源。只要在不同语言的文件夹中提供字符串映射即可,如果当前系统语言没有支持,会使用 base 中的资源。通过 $r('app.string.xxx') 访问对应的字符串: 注:资源对象类型是 Resource,可以将 AppBar 组件中 title 属性类型设置为 string | Resource ,表示该属性既可以设置为 string 也可以设置为 Resource 对象: @Componentstruct AppBar { private title: string | Resource = '' ;
这里提交一个小里程碑 计数器-v4-资源使用[4]。
上面的截图可以看出,应用会有顶部的标题栏和底部导航栏,导致应用并没有全屏展示,下面就来看一下如何处理。参考官方文档 《开发应用沉浸式效果》[5] 1. 窗口全屏处理 首先我们需要在窗口启动时,将窗口设置为全屏。这个操作需要在 entry/src/main/ets/entryability/EntryAbility.ets 文件中处理。 onWindowStageCreate 回调可以监听到窗口创建的时机: ---->[ets/entryability/EntryAbility.ets]----let windowClass: window .Window = windowStage.getMainWindowSync(); // 获取应用主窗口 // 1. 设置窗口全屏 let isLayoutFullScreen = true ; windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => { console .info('Succeeded in setting the window layout to full-screen mode.' ); }).catch((err: BusinessError ) => { console .error('Failed to set the window layout to full-screen mode. Cause:' + JSON .stringify(err));
});
如果只是设置为全屏,那么顶部和底部的界面元素将会出现重叠的问题(左图)。我们应该获取区域的高度,让界面元素避让状态栏和底部导航栏: 2. 获取窗口状态栏和导航栏高度 还是在刚才的 EntryAbility 文件中,在窗口创建时可以获取顶部状态栏和底部导航栏的高度,通过 AppStorage 可以将对象在全局存储起来;另外可以监听 avoidAreaChange 回调,当避让区域发生变化时,也可以及时更新: ---->[ets/entryability/EntryAbility.ets]----// 2. 获取布局避让遮挡的区域 let type = window .AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例 let avoidArea = windowClass.getWindowAvoidArea(type);let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度 AppStorage.setOrCreate('bottomRectHeight' , bottomRectHeight); type = window .AvoidAreaType.TYPE_SYSTEM; // 以状态栏避让为例 avoidArea = windowClass.getWindowAvoidArea(type);let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度 AppStorage.setOrCreate('topRectHeight' , topRectHeight);// 3. 注册监听函数,动态获取避让区域数据 windowClass.on('avoidAreaChange' , (data) => { if (data.type === window .AvoidAreaType.TYPE_SYSTEM) { let topRectHeight = data.area.topRect.height; AppStorage.setOrCreate('topRectHeight' , topRectHeight); } else if (data.type == window .AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { let bottomRectHeight = data.area.bottomRect.height; AppStorage.setOrCreate('bottomRectHeight' , bottomRectHeight); } });
3. 避让高度的获取和使用 顶部展示的组件是 AppBar,所以我们可以将避让的逻辑封装在 AppBar 中,如下所示, [1] : 通过 @StorageProp('名称') 可以访问存储在全局的对象。 [2]: 然后让 AppBar 的高度增加顶部的避让高度,并且内容距离上方有相应的内边距: [3]: 获取的避让高度是像素值,需要通过 px2pv 转换成虚拟像素。 @Component struct AppBar { private title: string | Resource = '' ; @StorageProp('topRectHeight' ) topRectHeight: number = 0 ; /// 略同... build() { /// 略同... .height(56 + px2vp(this .topRectHeight)) .padding({ left: 8 , right: 8 ,top: px2vp(this .topRectHeight) }) .justifyContent(FlexAlign.SpaceBetween) } }
同理,底部区域的避让,可以让整体距离底部指定高度: 这里提交一个小里程碑 计数器-v5-沉浸标题栏[6]。大家可以把这篇文章的知识点通过树形结构记录一下,下一篇开始时我会给出我的 ~
到这里,我们就了解了资源使用的方式,以及如何处理沉浸标题栏。后续将继续鸿蒙纪元的进程,通过一些有趣的小功能,体验和入门鸿蒙的开发,我们下次再见~ [1] 张风捷特烈:
https://juejin.cn/user/149189281194766[2] HarmonyUnit: [3] 资源目录结构:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/resource-categories-and-access-V5#%E8%B5%84%E6%BA%90%E7%9B%AE%E5%BD%95[4] 计数器-v4-资源使用:
https://github.com/toly1994328/HarmonyUnit/tree/91b21c46756c7876a0a153eae656fe88c23d9459[5] 《开发应用沉浸式效果》:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-develop-apply-immersive-effects-V5#section202081847174413[6] 计数器-v5-沉浸标题栏:
https://github.com/toly1994328/HarmonyUnit/tree/c9174be6182616a1f6b5c3944d63491bf905d1b9[7] 张风捷特烈:
https://juejin.cn/user/149189281194766[8] 张风捷特烈:
https://space.bilibili.com/390457600
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
推荐阅读 :
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!