OpenHarmony 4.1 SDK11 北向应用开发笔记

目录

声明

1、开启其他应用

2、延时切换页面

3、设置页面切换效果

4、设置背景图片和背景铺满屏幕

5、设置隐藏状态和导航条

6、设置组件大小和对齐方式

7、设置按钮类型改变按钮边框圆角半径

8、常用布局方式

9、布局技巧

10、动态创建组件

11、自定义组件

12、装饰器

自定义构造函数的参数传递

13、自定义数据类型

14、自定义子组件的事件如何传递回父组件进行处理

声明
本笔记基于OpenHarmony 4.1 SDK11,对于其他版本不一定适用 ,另外DevEco Studio版本为5.0.3 其他版本可能无法识别openharmony 4.1设备,比如5.0.5

1、开启其他应用
依赖的引用

import Want from '@ohos.app.ability.Want';
.onClick((event) => {
let want: Want = {
"deviceId": "",
"bundleName": "com.ohos.settings",
"abilityName": "com.ohos.settings.MainAbility"
};
this.context.startAbility(want).then(() => {
console.info('startAbility success');
}).catch((error: BusinessError) => {
console.info('startAbility failed');
})

2、延时切换页面
添加新的页面需要在src/main/resources/base/profile/main_pages.json 中添加新增的页面路径

{
"src": [
"pages/Index",
"pages/Second",
"pages/Third"
]
}
然后在pages目录下创建新的ets文件

依赖的引用

import { router } from '@kit.ArkUI';
放在build() {}后面

timerid = setTimeout(() => {
router.pushUrl({url:'pages/Iden'});
}, 3000); // 延时3秒后跳转到下一个页面
3、设置页面切换效果
放在build() {}后面

pageTransition() {
PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom)
PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.END)
}
4、设置背景图片和背景铺满屏幕
先在media中添加图片

.backgroundImage($r('app.media.idenbackground'))
.backgroundImageSize(ImageSize.FILL)
5、设置隐藏状态和导航条

1)当我们应用的Alility继承的是UIAbility时,可以onWindowStageCreate(windowStage: window.WindowStage)方法中实现如下操作:

windowStage.getMainWindowSync().setWindowSystemBarEnable([/*'status', */'navigation'])

2)当我们应用的Alility继承的是ServiceExtensionAbility时,可以在Window.createWindow中获取到window对象,然后调用如下操作:

window.setWindowSystemBarEnable([/*'status', */'navigation'])
status:状态栏 navigation:导航栏,注释 ‘status’,状态栏不显示,注释 ‘navigation’,导航栏不显示 ,都注释,就是都不显示

6、设置组件大小和对齐方式
.width(743)
.height(800)
.align(Alignment.Center)
7、设置按钮类型改变按钮边框圆角半径
Button(this.txt_button, {type: ButtonType.Normal})
.id('xxxx')
.fontSize(30)
.borderRadius(12)
8、常用布局方式
1、纵向布局方式:Column

2、横向布局方式:Row

3、叠加布局方式:Stack

9、布局技巧
1)使用 .layoutWeight(1) 属性使子组件填满父组件剩余空间或设置子组件权重

2)使用 .justifyContent(FlexAlign.SpaceEvenly) 使子组件在父组件中均衡分布

3)使用 .margin(18) 使组件与周边组件分开一定距离

4)使用 Blank() 空组件,使子组件在父组件的主轴方向隔开一定距离

10、动态创建组件
使用ForEach 和 if/else 可以循环和根据条件动态创建组件,可参考官方教程天气预报

knowledge_demo_entainment: 基于影音娱乐场景打造相关OpenHarmony音视频和游戏等样例,开发者不仅可以体验到最新最全的OpenHarmony音视频特性、应用开发框架,而且还可以从分布式流转等特性中感受万物互联带来的美妙。 - Gitee.com

List({ space: 8, initialIndex: 0 }) {
ForEach(this.cityArr, (item) => {
ListItem() {
if (this.selectCity.locationName == item.locationName) {
Text(item.locationName)
.width('100%')
.fontSize(20)
.fontColor('#E64F7EFD')
.backgroundColor('#1A4F7EFD')
.padding({ top: 10, bottom: 10, left: 22 })
} else {
Text(item.locationName)
.width('100%')
.fontSize(20)
.borderRadius(10)
.fontColor('#E6000000')
.padding({ top: 10, bottom: 10, left: 22 })
}
}.onClick(() => {
this.selectCity = item
this.isShowSideBar = !this.isShowSideBar;
})
})
}

11、自定义组件
需要重复使用的布局可以做成自定义组件,使用 @Component 装饰后使用 export导出

@Component
export default struct SideBar {
12、装饰器
被装饰器装饰过的代码会具有特殊的能力,比如我们的第一个页面Index页面是被

@Entry 装饰的,它装饰的struct 可以作为页面的入口组件。
@Component 装饰器也用于装饰struct 被其装饰过后,可以作为组件。
@State 装饰器用于装饰变量,被其装饰过后,与变量相关的组件会在变量发生变化自动重新渲染。
@State cityArr: CityModel[] = [ //城市列表
@Link 装饰器用于装饰子组件中的变量,被其装饰过后,该变量和父组件中的变量会双向绑定。类似C++中引用的作用。可以用于将子组件中的变化传回父组件中。
@Link isShowSideBar: boolean;
@Link selectCity: CityModel;
@Builder装饰器 可以用于装饰 函数,被其装饰过的函数可用于构造组件。作用类似于同一个文件中定义一个函数。也用于需要重复使用的组件。

@Builder function ABuilder(paramA1: string) {
Row() {
Text(UseStateVarByValue: ${paramA1} )
}
自定义构造函数的参数传递
1、按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。ArkUI提供$$作为按引用传递参数的范式。

2、调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。

class ABuilderParam {
paramA1: string = ''
paramB1: string = ''
}

@Builder function ABuilder($$ : ABuilderParam) {...}

ABuilder({ paramA1: this.label })
13、自定义数据类型
可以在单独的ets文件中定义数据类型 使用export导出

export class WeatherUiModel {
nowTemp; //当日气温
nowWeatherText; //未来两小时 天气状况的文字描述,包括阴晴雨雪等天气状态的描述
tempMax; //最高气温
tempMin; //最低气温
category; //空气质量
precip; //降雨量,大于0有雨
hourlyTemp: { temp }[]; //小时温度
iconDays: { iconDay }[]; //每日天气状况图标
date; //日期
day; //星期
dayArr: string[]; //星期数组
hoursArr: string[]; //时间数组
}

引用的方法

import { WeatherUiModel } from '../model/WeatherUiModel'

@State weatherUiModel: WeatherUiModel = {
nowTemp: 0,
nowWeatherText: 0,
tempMax: 0,
tempMin: 0,
category: 0,
precip: 0,
hourlyTemp: [],
iconDays: [],
date: '-月-日',
day: '',
dayArr: utils.getDayArr(),
hoursArr: utils.getHoursArr(),
};

14、自定义子组件的事件如何传递回父组件进行处理
ArkUI目前不支持事件传递链,可通过状态同步@Link或@Provide和@Consume进行父子组件间的状态通知,结合@Watch可以将状态变量的修改在组件间传递,实现类似的功能。--官方文档的内容

@Watch 装饰器用法

@Entry
@Component
struct Player {
//使用@Watch监听isPlaying,当isPlaying发生变化的时候执行valueChange方法
@State @Watch("valueChange") isPlaying: boolean = false

build() {
Column() {
PlayButton({ buttonPlaying: $isPlaying })
Text(Player is ${this.isPlaying ? '' : 'not'} playing).fontSize(30).onClick(() => {
this.isPlaying = !this.isPlaying;
})
}
}
/**

  • 当isPlaying的值发生变化的时候执行valueChange方法
  • @param propName 值为isPlaying
    */
    valueChange(propName: string): void {
    console.log("invoke valueChange method " + propName)
    }
    }

@Component
struct PlayButton {
@Link buttonPlaying: boolean
build() {
Column() {
Button() {
Text(this.buttonPlaying ? '暂停' : '播放')
.textAlign(TextAlign.Center).fontSize(30).width('100%')
}.onClick(() => {
this.buttonPlaying = !this.buttonPlaying
})
}
}
}

15、切换应用沙箱视角
在调试过程中,如果权限不对或文件不存在,开发者需要从调试进程视角切换为应用视角,以便直观分析权限及文件目录问题。视角切换命令如下:

hdc shell // 进入shell
ps -ef|grep [hapName] // 通过ps命令找到对应应用的pid
nsenter -t [hapPid] -m /bin/sh // 通过上一步找到的应用pid进入对应应用的沙箱环境中
执行完成后,即切换到了应用视角,该视角下的目录路径为应用沙箱路径,可以去排查沙箱路径相关问题。

16、组件外事件触发组件内数据更新机制emit 消息订阅与发送机制
定义类使用单例可以在组件间传递数据,但是无法触发组件内@State 修饰的变量刷新页面 emit可以及时的在组件外刷新组件,比如在native端,可以用回调函数触发ArkTs端发送消息触发页面刷新。

1)订阅消息

let innerEvent: emitter.InnerEvent = {
eventId: 1
};

// 收到eventId为1的事件后执行回调函数
emitter.on(innerEvent, () => {
console.info('callback');
});
2)发送消息

let eventData: emitter.EventData = {
data: {
"content": "c",
"id": 1,
}
};

let innerEvent: emitter.InnerEvent = {
eventId: 1,
priority: emitter.EventPriority.HIGH
};

emitter.emit(innerEvent, eventData);

posted @ 2026-07-10 22:18  13年程序员  阅读(9)  评论(0)    收藏  举报