当前位置: 首页 > news >正文

快速入门HarmonyOS应用开发(一)

目录

前言

一、准备工作

二、实战开发

2.1、Navigation简介

2.2、页面路由开发

2.2.1、创建常量

2.2.2、创建字符串资源

2.2.3、创建float资源

2.2.4、创建color资源

2.2.5、创建数据实体

2.2.6、创建页面路由表

2.2.7、创建Navigation根容器

2.2.8、创建NavDestination子页面

2.2.9、页面路由跳转及传参

2.2.10、处理页面返回键

前言

写这个系列的目标是准备通过几篇文章的介绍,和大家一起快速入门HarmonyOS应用的开发。初步打算是主要通过代码实战的形式去介绍,基本的语法和使用还是建议大家先阅读官网的文档说明。OK,话不多说,咱们开始。

一、准备工作

首先,最全面的学习资料肯定是官网文档,所以需要快速掌握文档的对应位置,这里把开发中经常用到文档入口都罗列在下面了,按需自取:

开发指南         API文档         最佳实践         FAQ        示例代码

其次,注意搜索时左侧菜单可以选择类别,比如这里可以勾选全部:

OK,接着咱们下载开发工具:下载与安装DevEco Studio,这个没什么好说的,下载完了之后一步一步安装即可。

接着学习开发语言可以参考如下内容,鸿蒙中使用的ArkTS是基于TypeScript做了扩展:

学习ArkTS语言和应用框架中的ArkTs(方舟编程语言)

准备工作就做到这里,接下来就可以上手开发了,今天咱们首先来学习路由如何使用。

二、实战开发

2.1、Navigation简介

Navigation主要用于实现Navigation页面(NavDestination)间的跳转,支持在不同Navigation页面间传递参数,提供灵活的入栈出栈操作,方便快捷的实现对不同页面的访问和复用。关于Navigation更多的介绍及详细使用大家可以参考:

组件导航(Navigation) (推荐)

2.2、页面路由开发

首先我们先创建一个空工程,这里可以根据公司规范或者个人习惯修改相关文件名。在src/main/ets/pages目录下新建navigation文件夹,将Index.ets移动到该文件夹下,并修改文件名为NavigationPage.ets,并且修改代码中Index名称为NavigationPage,同时还需要修改EntryAbility文件中默认加载的页面路径:

上面的NavigationPage作为整个工程页面路由栈的根页面,你可以把它理解为一个相册,我们使用@Entry来修饰它,并且使用Navigation作为它的组件树的根节点。然后我们需要实现的APP的各个展示页面就是相册里面的一张一张的照片,我们使用@Component来修饰它,并且使用NavDestination作为它们的组件树的根节点。简单理解就是:Navigation是容器,NavDestination是页面。在今天的例子中,我们会创建两个页面MainPage和OtherPage。

今天由于是本系列的第一篇,所以一些基础工作我也会介绍一下,后续的文章中将不再赘述。

2.2.1、创建常量

在工程的src/main/ets 目录下新建文件夹constants,用来存放项目中需要用到的常量字段,这里我们创建两个文件:CommonConstant存放公共常量,PageConstant存放页面名称,代码如下:

export class CommonConstant {static readonly FULL_PERCENT: string = '100%'static readonly PAGEINFO_KEY: string = 'PageInfo'static readonly EXIT_INFO: string = '再按一次退出应用'static readonly PRE_TIME: number = 0static readonly EXIT_TIME: number = 2000
}
export class PageConstant{static readonly PAGE_MAIN: string = 'MainPage'static readonly PAGE_OTHER: string = 'OtherPage'
}

2.2.2、创建字符串资源

在resources/base/elment/string.json文件中添加项目中需要用到的字符串资源:

{"string": [{"name": "tip_main_page","value": "我是主页点我跳转"},{"name": "tip_other_page","value": "我是其它页面"}]
}

2.2.3、创建float资源

在resources/base/elment/float.json文件中添加项目中需要用到的字体大小fp和组件大小vp资源:

{"float": [{"name": "fp_20","value": "20fp"},{"name": "vp_100","value": "100vp"}]
}

2.2.4、创建color资源

在resources/base/elment/color.json文件中添加项目中需要用到的颜色资源:

{"color": [{"name": "color_primiry","value": "#57BE6A"}]
}

2.2.5、创建数据实体

在src/main/ets下新建model文件夹,在该文件夹下新建DemoData.ets文件,在这个文件里我们创建页面间传值所需的数据类,这里介绍了两种方式interface和class,都可以定义所需的实体:

// MainPage传递参数的数据类
export interface ParamData {name: string
}// OtherPage回传的数据类
export class BackData {result?: stringconstructor(result: string) {this.result = result}
}

2.2.6、创建页面路由表

在src/main/ets/pages/navigaion目录下新建PagesMapBuilder.ets文件,作为项目的页面路由表:

import { PageConstant } from "../../constants/PageConstant";
import { MainPage } from "../MainPage";
import { OtherPage } from "../OtherPage";@Builder
export function PagesMapBuilder(name: string) {if (name===PageConstant.PAGE_MAIN) {MainPage()}else if (name===PageConstant.PAGE_OTHER){OtherPage()}
}

2.2.7、创建Navigation根容器

在NavigationPage页面中,我们实例化了一个NavPathStack对象:

// 页面路由栈
@Provide(CommonConstant.PAGEINFO_KEY) pageStack: NavPathStack = new NavPathStack()

从名字也能看出它是用来管理页面路由的路由栈对象,这里我们使用了@Provide这个装饰器来修饰,它一般是与@Consume成对使用,用于与后代组件的双向数据同步、状态数据在多个层级之间传递的场景。使用详情可以参考:@Provide装饰器和@Consume装饰器:与后代组件双向同步

然后在build()函数中,我们创建Navigation组件并且绑定导航控制器和页面路由表:

import { CommonConstant } from '../../constants/CommonConstant'
import { PagesMapBuilder } from './PagesMapBuilder'@Entry
@Component
struct NavigationPage {// 页面路由栈@Provide(CommonConstant.PAGEINFO_KEY) pageStack: NavPathStack = new NavPathStack()build() {Navigation(this.pageStack).hideTitleBar(true).hideToolBar(true).hideNavBar(true).mode(NavigationMode.Stack).navDestination(PagesMapBuilder)}
}

这里的build()函数是用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。从这里也就看出了HarmonyOS应用的UI是使用的声明式UI,这里提到了它是用于自定义组件的UI描述,因此咱们这里的NavigationPage也是自定义组件,你可以理解在HarmonyOS应用中:一切皆组件!

关于自定义组件的使用可以参考:创建自定义组件

可以看到,我们代码中的@Component  struct正是符合这个结构的,至于最上面的@Entry,那是因为它装饰的自定义组件是UI页面的入口。

2.2.8、创建NavDestination子页面

在src/main/ets/pages文件夹下新建MainPage.ets文件,在这个文件中首先定义路由栈对象,承接上文中的@Provide,这里我们可以直接使用@Consume来定义:

@Consume(CommonConstant.PAGEINFO_KEY) pageStack: NavPathStack

然后在build()函数中创建NavDestination为根节点的组件树,这里面我们仅添加一个Text文本用于展示:

import { CommonConstant } from "../constants/CommonConstant"@Component
export struct MainPage {@Consume(CommonConstant.PAGEINFO_KEY) pageStack: NavPathStack@State content: string | Resource = $r('app.string.tip_main_page')build() {NavDestination() {Column() {Text(this.content).fontSize($r('app.float.fp_20')).fontColor(Color.Blue).fontWeight(FontWeight.Bold)}.width(CommonConstant.FULL_PERCENT).height(CommonConstant.FULL_PERCENT).justifyContent(FlexAlign.Center)}.hideTitleBar(true)}
}

这里的@State同样是一个状态管理的装饰器,用它修饰的变量在组件内数据变更时可以引起UI的自动刷新,具体使用可以参考:@State装饰器:组件内状态

然后以同样的方式创建另一个页面OtherPage.ets:

import { CommonConstant } from "../constants/CommonConstant"@Component
export struct OtherPage {@Consume(CommonConstant.PAGEINFO_KEY) pageStack: NavPathStack@State content: string | Resource = $r('app.string.tip_other_page')build() {NavDestination() {Column() {Text(this.content).fontSize($r('app.float.fp_20')).fontColor(Color.Blue).fontWeight(FontWeight.Bold).onClick(() => {let backData = new BackData('我是Other数据')this.pageStack.pop(backData)})}.width(CommonConstant.FULL_PERCENT).height(CommonConstant.FULL_PERCENT).justifyContent(FlexAlign.Center)}.hideTitleBar(true)}
}

2.2.9、页面路由跳转及传参

首先在NavigationPage的aboutToAppear()回调中添加第一个加载的页面视图:

aboutToAppear(): void {this.pageStack.pushPath({ name: PageConstant.PAGE_MAIN }, false)
}

aboutToAppear()是自定义组件的一个生命周期函数,在组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build函数之前执行,详情可以参考:

自定义组件生命周期

然后在MainPage中创建需要传递的参数:

paramData: ParamData = { name: '我是MainPage数据' }

在MainPage中的Text文本的点击事件里,跳转到OtherPage页面,并将上面的数据作为参数传递过去,同时在onPop回调中可以接收OtherPage页面回传的参数,如果不需要回传参数onPop回调可以不用写:

.onClick(() => {// 页面跳转,传递参数到Other页面,并通过onPop回调接收Other页面回传的数据this.pageStack.pushPath({name: PageConstant.PAGE_OTHER, param: this.paramData, onPop: (popInfo: PopInfo) => {let backData = popInfo.result as BackDatathis.content = backData.result}})})

接着在OtherPage页面中接收来自MainPage传递的参数,这里接收参数我们介绍两种方式:

第一种:使用NavDestination的onReady()函数进行接收:

.onReady((context: NavDestinationContext) => {this.paramData = context.pathInfo.param as ParamDataif (this.paramData) {this.content = this.paramData.name}})

第二种:在aboutToAppear()生命周期函数中通过pageStack的getParamByIndex()函数接收:

aboutToAppear(): void {this.paramData = this.pageStack.getParamByIndex(this.pageStack.size() - 1) as ParamDataif (this.paramData) {this.content = this.paramData.name}}

然后在OtherPage的Text文本的点击事件中我们将需要回传的参数通过pageStack的pop(xxx)方法进行回传:

.onClick(() => {let backData = new BackData('我是Other数据')this.pageStack.pop(backData)})

2.2.10、处理页面返回键

在Android中我们经常可以看到在点击Back键时会提示:再按一次退出应用,虽然现在很多手机隐藏了返回键,但是我们通过侧滑仍然可以出发页面返回,那如果想要实现上面的效果该怎么做呢?

其实原理是类似的,在HarmonyOS中,我们可以监听页面的onBackPress()事件,在这个函数中处理连续点按退出应用的逻辑:

import { CommonConstant } from '../../constants/CommonConstant'
import { common } from '@kit.AbilityKit'@Entry
@Component
struct NavigationPage {private context = this.getUIContext().getHostContext() as common.UIAbilityContextprivate preTime: number = CommonConstant.PRE_TIMEpromptAction = this.getUIContext().getPromptAction()// 2秒内连续点按/侧滑后关闭当前应用onBackPress(): boolean | void {let currentTime = new Date().getTime()let flag = currentTime - this.preTimeif (flag > CommonConstant.EXIT_TIME) {this.preTime = currentTimethis.promptAction.showToast({ message: CommonConstant.EXIT_INFO })return true} else {this.context.terminateSelf()}return false}
}

最后来看一下实现的效果吧:

实现效果录屏

完整代码:HarmonyDemos

OK,今天的内容到这里就要和大家说再见了,咱们下期再会!

祝:工作顺利,前程似锦!


文章转载自:

http://W6eULnkJ.xjLgt.cn
http://Lu4B7U1S.xjLgt.cn
http://51KHJqhL.xjLgt.cn
http://cJJWThAC.xjLgt.cn
http://Sls134Kf.xjLgt.cn
http://DJKTXglX.xjLgt.cn
http://W5MlRuFi.xjLgt.cn
http://G1bVwVhw.xjLgt.cn
http://DXihIe6T.xjLgt.cn
http://jS1skVjB.xjLgt.cn
http://s9gZgBll.xjLgt.cn
http://vOKiUMkr.xjLgt.cn
http://5gBXeJPi.xjLgt.cn
http://AlKfJIdf.xjLgt.cn
http://igPewCel.xjLgt.cn
http://hiqSzEkw.xjLgt.cn
http://i23iJfy8.xjLgt.cn
http://LLcTMZGe.xjLgt.cn
http://5EfhOEQB.xjLgt.cn
http://asfXxWkI.xjLgt.cn
http://gylL2iBG.xjLgt.cn
http://5v0UTp5i.xjLgt.cn
http://w3tsbVw1.xjLgt.cn
http://ctvUrl90.xjLgt.cn
http://fWrUGOak.xjLgt.cn
http://bzXsxleL.xjLgt.cn
http://tF0bYlyN.xjLgt.cn
http://RTE7y6j4.xjLgt.cn
http://5GKIsTA0.xjLgt.cn
http://PeIUMGrx.xjLgt.cn
http://www.dtcms.com/a/385042.html

相关文章:

  • 深入解析 `pthread_detach`:告别线程的优雅之道
  • Arduino 通讯接口全景解析:从硬件到软件的跨板对话艺术
  • Python3练习题
  • AI GEO 实战:借百度文小言优化,让企业名称成搜索热词
  • 数字图像处理(1)OpenCV C++ Opencv Python显示图像和视频
  • 《拆解Unity开发顽疾:从UI渲染异常到物理交互失效的实战排障手册》
  • 安装和初始化配置Git
  • 蓝牙BLE调制端GFSK高斯滤波查表设计原理
  • PPO算法-强化学习
  • Spring Boot 实战:优雅地将配置文件映射为Java配置类并自动注入
  • ADC转换原理与应用详解
  • 第五章 搭建ZYNQ视频图像处理系统——软件设计
  • Chapter6—原型模式
  • Java字符串操作:从入门到精通
  • 如何科学评估CMS系统性能优化效果?
  • 批量更新和批量插入,内含jdbc工具类
  • 3D地球可视化教程 - 第2篇:夜晚纹理与着色器入门
  • Ajax笔记2
  • DDoS高防IP是什么? DDoS攻击会暴露IP吗?
  • Java 设计模式——原则:从理论约束到项目落地指南
  • 从零开始打造个性化浏览器导航扩展:极简高级风格设计
  • 软件包安装
  • QARM:Quantitative Alignment Multi-Modal Recommendation at Kuaishou
  • 通达信抓波段指标(主图)
  • Django基础环境入门
  • Java学习笔记2——简单语法
  • LLM-LLM大语言模型快速认识
  • Winogender:衡量NLP模型性别偏见的基准数据集
  • Oracle UNDO表空间使用率过高解决方案
  • Qt 中 OPC UA 通讯实战