鸿蒙纪·系列教程#03 | 沉浸状态栏与资源使用
The following article is from 编程之王 Author 张风捷特烈
《鸿蒙纪元》 是 张风捷特烈[1] 计划打造的一套 HarmonyOS 开发系列教程合集。致力于创作优质的鸿蒙原生学习资源,帮助开发者进入纯血鸿蒙的开发之中。本系列的所有代码将开源在 HarmonyUnit[2] 项目中:
github: https://github.com/toly1994328/HarmonyUnit
gitee: https://gitee.com/toly1994328/HarmonyUnit
[3]. 了解鸿蒙开发时文字、视图尺寸单位,统一配置常量资源。
官方文档中对资源目录结构[3]有详细的介绍,目前我们主要使用 base 的 media 文件夹中放置媒体数据,比如图片、音频;在 element 文件夹中放置字符串、颜色等常量资源。
1. 图片文件的使用
现在,我们的目标是将这两个图片资源放置在计数器 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)
}
@Builder
tailing() {
Button(){
Image($r('app.media.more'))
.width(24).height(24)
.fillColor(Color.White)
}
.width(36).height(36)
.backgroundColor(Color.Transparent)
}
2.常量数值资源
比如计数器中,按钮颜色、AppBAr 颜色都是一样的,我们想要定义一个主题色,方便统一维护。可以在 color.json 中增加一个 theme_color 的元素,指定对应的值, 在代码中通过 $r 访问资源设置即可。
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
},
{
"name": "theme_color",
"value": "#317bd4"
}
]
}
3. 了解像素单位
我们知道屏幕是由一个个像素点构成的, 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"
}
]
}
4. 国际化资源配置
---->[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": "下面是你点击按钮的次数:"
}
@Component
struct AppBar {
private title: string | Resource = '';
这里提交一个小里程碑 计数器-v4-资源使用[4]。
1. 窗口全屏处理
---->[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. 获取窗口状态栏和导航栏高度
---->[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. 避让高度的获取和使用
@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^)┛明天见!