先贴鸿蒙认证
官网10个类别总结如下
https://developer.huawei.com/consumer/cn/training/dev-cert-detail/101666948302721398
10节课学习完考试
考试 90分合格 3次机会 1个小时 不能切屏
运行hello world
hvigorfile.ts是工程级编译构建任务脚本
build-profile.json5是工程级配置信息,包括签名、产品配置等。
oh-package.json5是工程级依赖配置文件,用于记录引入包的配置信息。
oh_modules是工程的依赖包,存放工程依赖的源文件。
entry是应用的主模块,存放HarmonyOS应用的代码、资源等。
appScope-> app.json5 全局的配置文件
entry>src>main>module.json5 模块的配置文件
src/main/resources/base/profile/main_pages.json 页面page的路径配置信息,所有需要进行路由跳转的page页面都要在这里进行配置。
@Entry指明是页面入口组件
生命周期:
容器组件:
Row() {
元素1()
元素2()
}
页面生命周期 onPageShow onPageHide onBackPress
组件生命周期 aboutToAppear aboutToDisappear
控制渲染: if() {} else {}
循环渲染: ForEach(数组, 控制渲染函数(也就是生成器函数), 生成key函数)
定义状态: @State count: number = 0;
$r用于引用在 resources 目录下的资源
UIAbility 应用程序入口,一个应用可以有多个UIAbility
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。每一个UIAbility实例都对应持有一个WindowStage实例。(WindowStage为本地窗口管理器,用于管理窗口相关的内容)
在entry>src>main>ets>entryablity下初始会生成一个UIAbility文件以及在在entry>src>main>ets>pages下生成一个index.ets文件
启动模式: UIAbility当前支持singleton(单实例模式)、multiton(多实例模式)和specified(指定实例模式)3种启动模式。 在module.json5文件中的“launchType”字段配置为“singleton”即可配置启动模式。
页面跳转并携带参数:import router from '@ohos.router' 调用router.pushUrl({url:'pages/Secord', params: {ttt: 'asdf'}})即可
路由跳转模式:默认情况下的启动模式为Single(mode参数配置为router.RouterMode.Single单实例模式和router.RouterMode.Standard多实例模式。 )
路由跳转逻辑: 在单实例模式下:如果目标页面的url在页面栈中已经存在同url页面,离栈顶最近同url页面会被移动到栈顶,移动后的页面为新建页,原来的页面仍然存在栈中,页面栈的元素数量不变;如果目标页面的url在页面栈中不存在同url页面,按多实例模式跳转,页面栈的元素数量会加1。
接受页面参数:@State ttt: string = router.getParams()?.['ttt'] 通过this.ttt使用
页面返回:router.back()
UIAbility生命周期:
onCreate(在UIAbility实例创建完成时触发在此回调中进行应用初始化操作,例如变量定义、资源加载等。)
onForeground(在UIAbility的UI界面可见之前触发,如UIAbility切换至前台时 可以在此回调中申请系统需要的资源)
onBackground(在UIAbility的UI界面完全不可见之后触发,如UIAbility切换至后台时。可以在此回调中释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等)
onDestroy(在UIAbility实例销毁时触发。可以在此回调中进行系统资源的释放、数据的保存等操作。)
基础组件
Text(‘文本’).fontSIze(‘24fp’).fontColor($r(‘app.color.title_text_color’)).fontWeight(500)
使用resource资源时需要在resources下的float.json文件中定义文本大小 {“float”: [{“name”: “page_title_text_size”, “value”: “24fp”}]}
使用resource资源时需要在resources下的color.json文件中定义文本颜色,{“color”: [{“name”: “title_text_color”, “value”: “red”}]}
Image使用网络图片要在modules.json5的module内加上"requestPermissions": [{“name”: “ohos.permission.INTERNET”}], 建议优先使用resouces资源
TextInputController 动态设置光标位置
LoadingProgress组件用于显示加载进展
TextInput({placeholder: ‘账号’}).maxLength(11).type(InputType.Number).onChange((value: string) => {
this.text = value})
Button(‘登陆’, {type: ButtonType.Capsule})
容器组件
使用:Column() {} Row() {}
属性: justifyContent及alignItems属性和flex的一致
设置间距: Column(value: {space: 2}) {} Row(value: {space: 2}) {}
线性列表: List List一般和ListItem结合使用
List({space: 2, initialIndex: 1, scroller: Scroller}) scroller控制List组件滚动
divider分割线
事件监听: onScroll onScrollIndex(列表滑动时触发,返回值初始和结束索引)
排列方式: List组件里面的列表项默认是按垂直方向排列的,如果您想让列表沿水平方向排列,您可以将List组件的listDirection属性设置为Axis.Horizontal。
onReachStart(列表到达起始位置时触发) onReachEnd onScrollStop
List() {
ForEach(this.arr, (item: string) => { ListItem() { Text(`${item}`) } } )
}.divider({color: 'red'})
网格布局:Grid
Grid(scroller) scroller用来控制FGrid滚动
属性:columnsTemplate设置网格布局列的数量 rowsTemplate设置网格布局行的数量 columnsGap设置行与列的间距 rowsGap设置行与行的间距
Grid() {
ForEach(this.arr, (item: string) => {
GridItem() {
Text(`${item}`)
}
}, item => item)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.height(300)
Tabs: Tabs组件仅可包含子组件TabContent
Tabs({barPosition: BarPostion.start, vertical: false, index: 0, controller: TabsController }) controller用来控制tabs组件进行切换
Tabs属性:vertical设置为纵向默认为false barMode布局模式 barWidth barheight
位置:
1)BarPosition.Startvertical属性方法设置为false(默认值)时,页签位于容器顶部。 2)barPosition的值可以设置为BarPosition.Start(默认值) vertical属性方法设置为true时,页签位于容器左侧。
3)barPosition的值可以设置为BarPosition.End:vertical属性方法设置为false时,页签位于容器底部。
4)barPosition的值可以设置为BarPosition.End:vertical属性方法设置为true时,页签位于容器右侧。
private controller: TabsController = new TabsController()
Tabs({ barPosition: BarPosition.Start, controller: this.controller }){
TabContent() { Text('1')}
TabContent() {Text('2')}
}
.barHeight(60)
.onChange((index: number) => {
this.currentIndex = index;
})
使用DevEco Studio高效开发
诊断开发环境:Help > Diagnostic Tools > Diagnostic Devlopment Environment 全部时对勾代表成功
新旧文件迁移(早期npm换成ohpm):package .npmrc换成oh-package.json5 .ohpmrc
删除不适用的文件 package.json package-lock.json .npmrc node_modules
重新sync工程以前使用的新的包管理器 也可以点击通知处的自动化迁移
高效编辑代码:
代码自动 补齐 代码自动导包(alt+enter) 错误检查 快速查找(按住两次shift) 代码自动跳转(按住Ctrl键后单击)代码树(Alt + 7 / Ctrl + F12)代码引用查找
(在要查找的对象上,单击鼠标右键 > Find Usages或使用快捷键Alt +F7) 【代码折叠 注释 和vsocde一样】 快速查阅API接口及组件参考文档(选中需要查阅的接口或组件,单击鼠标右键 > Show in API Reference)
代码质量检查(编辑器出现蜗牛图标) 有的可以自动修复
预览器的使用
打开实时预览: view > Tool window > Previewer
预览器操作: 可以切换国际化语言
双向预览:点击inspector图标
多设备预览:开启多设备预览开关
页面预览:通过在工程的ets文件头部添加注解@Entry实现。
页面入口组件的装饰器是**@Entry**
三方库:
三方库获取: gitee harmonyos开发者官网(https://devecoservice.harmonyos.com/)
下载: 使用ohpm包管理工具下载, ohpm install @ohos/lottie, ohpm-package.json5中可以看到 存放位置在oh_modules中
使用:import lottie from '@ohos/lottie'
保存应用数据:
数据存储方式: 首选项 关系型数据库 分布式数据服务 分布式数据对象
首选项:适用于对key-value结构数据进行存取和持久化操作,是非关系型数据库,存取数据不要超过1万条,key字符长度不要超过80个字节 value长度不要超过8192字节 进程中每个文件仅存在一个Preferences实例 它不保证遵循ACID特性 通过flush方法把应用数据保存到文件中
import dataPreferences from '@ohos.data.preferences'
const PREFERENCES_NAME = 'myPreferences'
const KEY_APP_FONT_SIZE + "appFontSize'
context为上下文
dataPreferences.getPreferences(context, PREFERENCES_NAME)
.then(async (preferences) => {
此时可以增删改查
put保存数据
await preferences.put(KEY_APP_FONT_SIZE, 24)
flush持久化保存
preferences.flush()
})
has判断是否包含指定的key delete删除数据
读取数据
let fontSize: number = 0
const preferences = await globalThis.getFontPreferences()
fontSize = await preferences .get(KEY_APP_FONT_SIZE, fontSize)
给应用添加动画
属性动画: 产生属性动画的属性须在animation之前声明,其后声明的将不会产生属性动画。目前支持的属性包括width、height、position、opacity、backgroundColor、scale、rotate、translate等
添加属性动画:只需要给组件(包括基础组件和容器组件)添加animation属性 (delay延时播放时间 curve动画变化曲线 playMode动画播放模式 onFinish动画播放结束时回调 iterations播放次数 tempo播放速度)
.animation({duration: 2000, tempo: 3.0, delay: 400, curve: Curve.Linear, playMode: PlayMode.Alternate, iterations: -1})
最有可能导致onFinish不被回调的情况是iterations设置为 -1,因为这可能意味着过程会无限次地重复,从而没有“完成”的时候。
管理组件状态:
组件内状态管理@State
从父组件单向同步状态@Prop
父组件传递TargetListItem({isEditMode: this.isEditMode,})
子组件接收 @Prop isEditMode: boolean;
父子组件双向同步状态和 @Link 监听状态变化@Watch
父组件 @State clickIndex: number = 0
TargetListItem({clickIndex: $clickIndex}) // $代表引用
子组件 @Link @Watch('onClickIndexChanged') clickIndex: number
onClick(() => {this.clickIndex = this.index})
onClickIndexChanged() { if(this.clickIndex != this.index) this.isExpanded = false }
给应用增加视频播放功能
video 使用网络地址需要在module.json5添加网络访问权限
module: { reqPermissions: [{name: 'ohos.permission.INTERNET'}] }
video({src: this.source, previewUri: this.previewUris}).htight('100%').width('100%').objectFit(ImageFit.Contain)
自定义控制器:在配置控制器前需要.controls(false)
private controller: VideoController;
video({src: this.source, previewUri: this.previewUris, controller: this.controller}).controls(false).onPrepared((event)=>{ // event.duration为播放时长 }).onUpdate((event)=>{ // event.time为播放进度 }).onFinish(() => { //播放结束}).onError(() => { //播放出错})
VideoSlider({controller: this.controller}) 在 VideoSlider内自定义组件布局 this.controller.start() 控制播放 this.controller.pause()控制暂停 this.controller.setCurrentTime(100, SeekMode.Accurate)控制播放进度
给应用添加弹窗:
确认类 AlertDialog
选择类 TextPickerDialog DatePickerDialog TimePickerDialog
自定义弹窗 @CustomDialog
警告弹窗: 弹窗默认显示在屏幕中央
AlterDialog.show({
message: '当前数据未保存,是否离开?',
primaryButton: {
value: '取消',
action: () => {}
},
secondaryButton: {
value: '确定',
action: () => {}
},
alignment: DialogAlignment.Button,
offset: { dx: 0, dy: -20 }
})
选择弹窗-DatePickerDialog:
DatePickerDialog.show({
start: new Date('1900-1-1'),
end: new Date(),
selected: new Date('1990-1-1'),
lunar: false, // 选择是否未农历
onAccept: (value: DatePickerResult) => { let year = value.year; let month = value.month + 1}
})
文本选择弹窗-TextPickerDialog:
TextPickerDialog.show({
range: this.fruits, // 设置文本选择器的选择范围
selected: this.select, // 设置初始选中项的索引值。
onAccept: (value: TextPickerResult) => {
},
onCancel: () => { },
onChange: (value: TextPickerResult) => { }
})
自定义弹窗:
创建一个单独文件 顶部用@CustomDialog修饰 this.controller.close()来关闭弹窗
custonDialogController: CustomDialogController = new CustomDialogController({})得到控制弹窗
基于web组件构建网络应用
Web({src: '本地地址/网络地址', controller: WebController})
当访问本地地址时 src写法 $rawfile('index.html')
当访问网络地址,需要添加module: { reqPermissions: [{name: 'ohos.permission.INTERNET'}] }
this.controller.forward前进页面 controller.backward后退页面 controller.runJavaScript 异步执行js脚本并通过回调返回执行结果
原生页面调用web页面的方法: controller: WebController = new WebController()
this.controller.runJavaScript({script: 'test()'})
web属性:
fileAccess 默认开启通过$rawfile访问应用路径中的文件
javascriptAccess 默认开启运行执行js脚本
imageAccess默认开启允许自定加载图片资源
zoomAccess 网页缩放默认允许缩放
textZoomAtio 文本缩放
web事件:
onProgressChange可以监听网页的加载进度,
onPageEnd在网页加载完成时触发该回调,且只在主frame触发
onConfirm事件: 网页调用confirm方法告警时触发此回调
onConsole: 调试网络应用
Web(...).onConfirm(event => { console.log(event.url, event.message, event.result) })
.onConsole((event) => {
console.log(event.message.getMessage()event.message.getMessageLevel()); return false;
})
当onConfirm回调返回false时,触发默认弹窗。当回调返回true时,系统应用可以调用系统弹窗能力(包括确认和取消),并且需要根据用户的确认或取消操作调用JsResult通知Web组件。
使用HTTP访问网络:
使用:
添加权限module: { requestPermissons: [{name: 'ohos.permission.INTERNET'}] }
导包import http from '@ohos.net.http';
每一个httpRequest对象对应一个http请求任务,不可复用。
创建数据请求对象 let httpRequest = http.createHttp() // 返回的httpRequest 对象包含request destory on off方法
订阅请求头 httpRequest.on('headersReceive', (header) => { // 用JSON.stringify(header)解析头信息 })
发起请求 let promise = httpRequest.request('这是url', {
method: http.RequestMethod.Post,
extraData: { 'param1': 'value1' }, //发送请求的额外参数
connectTimeout: 60000, // 链接超时时间
readTimeout: 60000, // 读取超时时间
header: { 'Content-Type': 'application/json' }
})
处理响应 .then((value) => {
if(value.responseCode === 200) console.log(value.header, value.Result, value.cookies)
})