HarmonyOS应用开发-ArkTS基础知识

作者:杨亮Jerry

作为多年的大前端程序开发工作者,就目前的形式,个人浅见,在未来3-5年,移动端依旧是Android系统和iOS系统的天下。不过基于鸿蒙系统的应用开发还是值得我们去花点时间去了解下的,阅读并实践官网的开发文档和实践案例后,我们会发现其编程模式和Android的Jetpack Compose以及基于Dart语言开发Flutter跨平台应用程序非常相似,它们都是声明式的编程方式,非常容易理解。相信有过Compose或者Flutter开发经验的小伙伴去学习HarmonyOS应用开发会非常简单,容易上手。

虽然现在工作不是全部时间在Coding上了,但是自己在技术上还是要有所坚持,后续会抽时间继续学习HarmonyOS的开发,毕竟艺多不压身(天朝程序猿😂)。


一、ArkTS与TypeScript

1、声明式UI基本概念

(1)、应用界面是由一个个页面组成,ArkTS是由ArkUI框架提供,用于以声明式开发范式开发界面的语言。

(2)、声明式UI构建页面的过程,其实是组合组件的过程,声明式UI的思想,主要体现在两个方面:

  • 描述UI的呈现结果,而不关心过程
  • 状态驱动视图更新

2、按照官网上的说法,ArkTS是HarmonyOS的主力应用开发语言。

它在TypeScript(简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。

ArkTS、TypeScript和JavaScript之间的关系: JavaScript是一种属于网络的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。 TypeScript 是 JavaScript 的一个超集,它扩展了 JavaScript 的语法,通过在JavaScript的基础上添加静态类型定义构建而成,是一个开源的编程语言。 ArkTS兼容TypeScript语言,拓展了声明式UI、状态管理、并发任务等能力。

TypeScript的语法非常简单,有过Java、Kotlin、Dart等语言开发经验的小伙伴,会非常容易上手。可以在其官网进一步了解TS的语法知识。

3、ArkTS基础知识

(1)、ArkUI开发框架

上面这张图是ArkUI开发框架的整体架构,其中,基于TS扩展的声明式UI范式中所用的语言就是ArkTS。

(2)、ArkTS声明式开发范式

上面这张图是从官网下载下来的一个介绍ArkTS声明式开发范式 的代码示例,UI界面会显示两段文本和一个按钮,当开发者点击按钮时,文本内容会从’Hello World’变为‘Hello ArkUI’。

  • 装饰器 用来装饰类、结构体、方法以及变量,赋予其特殊的含义,如上述示例中 @Entry 、 @Component 、 @State 都是装饰器。具体而言, @Component 表示这是个自定义组件; @Entry 则表示这是个入口组件; @State 表示组件中的状态变量,此状态变化会引起 UI 变更。

  • 自定义组件 可复用的 UI 单元,可组合其它组件,如上述被 @Component 装饰的 struct Hello。

  • UI 描述 声明式的方式来描述 UI 的结构,如上述 build() 方法内部的代码块。

  • 内置组件 框架中默认内置的基础和布局组件,可直接被开发者调用,比如示例中的 Column、Text、Divider、Button。

  • 事件方法 用于添加组件对事件的响应逻辑,统一通过事件方法进行设置,如跟随在Button后面的onClick()。

  • 属性方法 用于组件属性的配置,统一通过属性方法进行设置,如fontSize()、width()、height()、color() 等,可通过链式调用的方式设置多项属性。

  • 状态管理 在应用开发中,除了UI的结构化描述之外,还有一个重要的方面:状态管理。如上述示例中,用 @State 装饰过的变量 myText ,包含了一个基础的状态管理机制,即 myText 的值的变化会自动触发相应的 UI 变更 (Text组件)。ArkUI 中进一步提供了多维度的状态管理机制。

二、ArkTS开发实践

接下来会按照官网的实例进行第一次ArkTS的开发实践,基于自己的理解进行一些修改,学习基本知识。

上面两张图就是我们要实现的UI效果和交互逻辑,即要呈现一个学生名单列表,每个Item由一个Icon和一个Name横向组成,当选中某一个Item的时候,Icon要切换成选中图标,另外Name的样式也会发生一些变化。使用ArkTS实现这个学生名单列表的方法基本和Jetpack Compose以及Flutter的开发方式是一样的,下面进行代码拆分。

1、自定义组件的组成

ArkTS 通过 struct 声明组件名,并通过 @Component@Entry 装饰器,来构成一个自定义组件。

使用 @Entry@Component 装饰的自定义组件作为页面的 入口,会在页面加载时首先进行渲染。

import { StudentListPage } from '../view/StudentListPage';

@Entry
@Component
struct Index {
  build() {
    Column() {
      StudentListPage();
    }
    .width('100%')
    .height('100%')
    .padding('10vp')
    .backgroundColor($r('app.color.page_background'))
  }
}

这个Index使用 @Entry@Component 装饰,所以会在页面加载时首先进行渲染,可以理解为当前页面的入口。

2.使用@Component装饰的自定义组件

如图所示,对列表进行了组件的拆分。

(1)、使用 @Component 来装饰自定义组件,组成学生列表的Item。在ArkTS中,对组件配置属性与布局方法很简单,支持链式调用。

(2)、状态:@State

使用 @State 装饰符改变组件状态,声明式UI的特点就是UI是随数据更改而自动刷新的,我们这里定义了一个类型为 boolean 的变量 isChecked,其被 @State 装饰后,框架内建立了数据和视图之间的绑定,其值的改变影响UI的显示。

@State isChecked: boolean = false;

  • 可以使用 if/else 表达式来渲染组件的显示与消失,当判断条件为true时,组建为已完成的状态,图片Icon显示选中图标,反之则为未完成状态,图片Iocn显示已选中状态。
  • ArkTS提供了 @Builder 装饰器,来修饰一个函数,快速生成布局内容,便面重复的UI描述内容。由于两个Image的实现具有大量重复代码,ArkTS提供了 @Builder 装饰器,来修饰一个函数,快速生成布局内容,从而可以避免重复的UI描述内容。这里使用 @Bulider 声明了一个 checkIcon 的函数,参数为url,对应要传给Image的图片路径。
@Builder checkIcon(icon: Resource) {
    Image(icon)
      .objectFit(ImageFit.Contain)
      .width($r('app.float.checkbox_width'))
      .height($r('app.float.checkbox_height'))
      .margin($r('app.float.checkbox_margin'))
  }
  • 字体使用了 三目运算符 来根据状态变化修改其透明度和文字样式,如opacity是控制透明度,decoration是文字是否有划线。通过 isChecked 的值来控制其变化。
Row() {
      if (this.isChecked) {
        this.checkIcon($r('app.media.ic_checked'))
      } else {
        this.checkIcon($r('app.media.ic_unchecked'))
      }

      Text(this.name)
        .fontColor(this.isChecked ? Color.Red : Color.Black)
        .fontSize(this.isChecked ? $r('app.float.item_checked_font_size') : $r('app.float.item_font_size'))
        .fontWeight(500)
        .opacity(this.isChecked ? 0.5 : 1.0)
        .decoration({ type: this.isChecked ? TextDecorationType.LineThrough : TextDecorationType.None })
    }
  • 在组件Row上添加 onClick 点击事件,根据 isChecked 状态的更改来触发UI的更新。
Row() {

    ...
    
    .borderRadius(22)
    .backgroundColor($r('app.color.start_window_background'))
    .width('100%')
    .height($r('app.float.list_item_height'))
    .onClick(() => {
      this.isChecked = !this.isChecked;
    })

(3)、StudentListItem 自定义组件完整代码(Item)

@Component
export default struct StudentListItem {
  @State isChecked: boolean = false;
  private name?: string;

  @Builder checkIcon(icon: Resource) {
    Image(icon)
      .objectFit(ImageFit.Contain)
      .width($r('app.float.checkbox_width'))
      .height($r('app.float.checkbox_height'))
      .margin($r('app.float.checkbox_margin'))
  }

  build() {
    Row() {
      if (this.isChecked) {
        this.checkIcon($r('app.media.ic_checked'))
      } else {
        this.checkIcon($r('app.media.ic_unchecked'))
      }

      Text(this.name)
        .fontColor(this.isChecked ? Color.Red : Color.Black)
        .fontSize(this.isChecked ? $r('app.float.item_checked_font_size') : $r('app.float.item_font_size'))
        .fontWeight(500)
        .opacity(this.isChecked ? 0.5 : 1.0)
        .decoration({ type: this.isChecked ? TextDecorationType.LineThrough : TextDecorationType.None })
    }
    .borderRadius(22)
    .backgroundColor($r('app.color.start_window_background'))
    .width('100%')
    .height($r('app.float.list_item_height'))
    .onClick(() => {
      this.isChecked = !this.isChecked;
    })
  }
}

3、循环渲染列表数据

ForEach基本使用中,只需要了解 要渲染的数据 以及要生成的 UI内容 两个部分,例如这里要渲染的数组为以上的几个学生名单,要渲染的内容是 StudentListItem 这个自定义组件,也可以是其他内置组件。

下面这张图是从官网上拷贝过来的,很清晰的描述了ForEach基本使用方式。

StudentListItem 这个自定义组件中,每一个 StudentListItem 要显示的文本参数 name 需要外部传入,参数传递使用 花括号 的形式,用 name 接受数组内的内容项item。

ForEach(this.studentList, (item: string) => {
        StudentListItem({ name: item })
      }, (item: string) => JSON.stringify(item))

StudentListPage的完整代码:

import DataModel from '../viewmodel/DataModel';
import StudentListItem from './StudentListItem';

@Component
export struct StudentListPage {
  private studentList: Array<string> = [];

  aboutToAppear() {
    this.studentList = DataModel.getStudentList();
  }

  build() {
    Column({ space: 16 }) {
      Text($r("app.string.Student_List_Title"))
        .fontSize('28fp')
        .fontWeight(FontWeight.Bold)
        .lineHeight('33vp')
        .width('100%')
        .margin({
          top: '24vp',
          bottom: '12vp',
        })
        .textAlign(TextAlign.Center)

      ForEach(this.studentList, (item: string) => {
        StudentListItem({ name: item })
      }, (item: string) => JSON.stringify(item))
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.page_background'))
  }
}

在组件生命周期 aboutToAppear() 中去初始化加载数据。

加载数据的Model的代码:

export class DataModel {
  private studentList: Array<string> = [
    "丁程鑫",
    "贺峻霖",
    "肖战",
    "成毅",
    "刘耀文",
    "李天泽",
    "马嘉祺",
  ];

  getStudentList(): Array<string> {
    return this.studentList;
  }
}

export default new DataModel();

总结

本文是根据HarmonyOs官网进行学习阅读 ArkTS开发语言介绍 基本课程的阅读笔记,以及实现了一个学生名单列表的简单页面的Demo样例 StudentListPage ,实现效果是使用 ForEach 实现了一个List列表,每个Item中使用了 Row 来实现横向布局,Row 中嵌套了 Icon 内置组件和 Text 内置组件,根据状态装饰符 @State 装饰的bool布尔变量 isChecked 值的改变,结合 if/else 表达式 、三目运算符 等来修改 IconText 组件的UI,其中又实用了 ArkTS 提供的 @Builder 装饰器,来修饰一个函数,快速生成布局内容,便面重复的UI描述内容。

整体来说,HramonyOS 使用 ArkTS 声明式语言的开发方式来描述 UI,这和 Jetpack Compose 开发、FlutterDart语言 跨平台开发、以及iOS的Swift开发方式非常相似,尤其组件名称和声明方式和Compose、Flutter非常相似,如果有过这几种系统、语言开发经验,上手HarmonyOS的ArkTS开发应该会很快。

虽然现在工作不是全部时间在Coding上了,但是自己在技术上还是要有所坚持,后续会抽时间继续学习HarmonyOS的开发,毕竟艺多不压身。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/120498.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

公共数据这座金矿,授权运营为何是赋能的关键路径?

数据要素市场化正开启下一个关键阶段。 自2014年大数据写入政府工作报告&#xff0c;到全国各地大数据交易所涌现&#xff0c;再到《数据二十条》颁布&#xff0c;中国数据要素产业探索之路已走过近十载。如今&#xff0c;国家大数据局正式成立&#xff0c;更是标志着数据要素…

2023数学建模国赛C题赛后总结

今天国赛的成绩终于出来了&#xff0c;盼星星盼月亮的。之前面试的时候已经把我给推到国奖评委那里去了&#xff0c;可是好可惜&#xff0c;最终以很微小的劣势错失国二。只拿到了广西区的省一。我心里还是很遗憾的&#xff0c;我真的为此准备了很久&#xff0c;虽然当中也有着…

vue3+setup 解决:this.$refs引用子组件报错 is not a function

一、如果在父组件中以下四步都没问题的话&#xff0c;再看下面步骤 二、如果父组件引用的是index页面 请在 头部加上以下代码 &#xff08;如果是form页面请忽略这一步&#xff09; <template> <a-modalv-model:visible"visible"title"头部名称&…

Dockerfile

文章目录 基本概念commit构建镜像常用指令拓展指令ARGUSERONBUILDHEALTHCHECK SpringBoot项目镜像构建Nginx项目镜像构建 基本概念 Docker为我们提供一个用于自定义构建镜像的一个配置文件。利用docker的build命令&#xff0c;指定dockerfile文件&#xff0c;就能按配置内容把…

数据仓库工具箱-零售业务

文章目录 一、维度模型设计的4步过程1.1 第一步&#xff1a;选择业务过程1.2 第二步&#xff1a;声明粒度1.3 第三步&#xff1a;确定维度1.4 第四步&#xff1a;确定事实 二、零售业务案例研究2.1 第一步&#xff1a;选择业务过程2.2 第二步&#xff1a;声明粒度2.3 第三步&am…

,多数据源+Mybatisplus + Sharding JDBC同一库中分表

水平分表是在同一个数据库内&#xff0c;把同一个表的数据按一定规则拆到多个表中,多数据源采用 mybatis-plus的dynamic-datasource 分库分表采用sharding-jdbc 数据库连接池管理是alibaba的druid-spring-boot-starter 同一个数据库内分表 目录 1.数据库表 2.配置 3.引入的…

企业计算机服务器中了360勒索病毒怎么办?勒索病毒解密,数据恢复

网络技术的不断发展给企业的生产与生活提供了极大的帮助&#xff0c;但随之而来的网络安全威胁也不断增加&#xff0c;近期&#xff0c;云天数据恢复中心的工程师接到了很多企业的求助&#xff0c;企业的计算机服务器数据库遭到了360后缀勒索病毒&#xff0c;通过对该病毒的检测…

如何使用Pyarmor保护你的Python脚本

目录 一、Pyarmor简介 二、使用Pyarmor保护Python脚本 1、安装Pyarmor 2、创建Pyarmor项目 3、添加Python脚本 4、配置执行环境 5、生成保护后的脚本 三、注意事项与未来发展 四、未来发展 五、总结 本文深入探讨了如何使用Pyarmor工具保护Python脚本。Pyarmor是一个…

MySQL数据脱敏(Data masking plugin functions)

对于企业而言&#xff0c;数据脱敏可以在数据共享或测试时用于保护敏感数据&#xff08;如信用卡&#xff0c;社保卡&#xff0c;地址等&#xff09;。通过对敏感数据进行脱敏处理&#xff0c;组织可以最大限度地降低数据泄露和未经授权访问的风险&#xff0c;同时仍能够使用真…

基于springboot+vue的影城管理系统

影城管理系统 编号&#xff1a;springboot33 源码合集&#xff1a; www.yuque.com/mick-hanyi/javaweb 源码下载&#xff1a;博主私 目 录 摘 要 1 前 言 2 第1章 概述 2 1.1 研究背景 3 1.2 研究目的 3 1.3 研究内容 4 第二章 开发技术介绍 5 2.1相关技术 5 2.2 Java技术 6…

二进制代码反汇编逆向工具:IDA Pro(WinMac)v7.7 汉化版

IDA Pro是一款交互式的、可编程的、可扩展的、多处理器的、交叉Windows或Linux WinCE MacOS平台主机来分析程序。它被公认为最好的花钱可以买到的逆向工程利器&#xff0c;已经成为事实上的分析敌意代码的标准并让其自身迅速成为攻击研究领域的重要工具。 IDA Pro的特点主要包括…

Mac 下安装golang环境

一、下载安装包 安装包下载地址 下载完成&#xff0c;直接继续----->下一步到结束即可安装成功&#xff1b; 安装成功之后&#xff0c;验证一下&#xff1b; go version二、配置环境变量 终端输入vim ~/.zshrc进入配置文件&#xff0c;输入i进行编辑 打开的不管是空文本…

Flink(二)【Flink 部署模式】

前言 今天是Flink学习的第二天&#xff0c;我的心情异常的复杂哈哈哈&#xff08;苦笑&#xff09;&#xff0c;学习上还是比较顺利的&#xff0c;感情上我并不擅长&#xff0c;所以心情波动大在所难免。害&#xff0c;至少还有学习让我不被各种糟糕琐碎的日常生活里的人和事所…

Mac下flutter工程配置Gitlab cicd打包(暂时仅限android侧)

写的太粗糙&#xff0c;可能不太适合完全不懂的同学&#xff0c;但是实在没时间&#xff0c;而且也不太会写&#xff0c;权当做一个记录吧&#xff0c;对了还没有搞docker这些&#xff0c;还在持续学习中 1.GitLab Runner&#xff08;打包机&#xff09; 注意:需要有对应的权…

关于卷积神经网络中如何计算卷积核大小(kernels)

首先需要说明的一点是&#xff0c;虽然卷积层得名于卷积&#xff08; convolution &#xff09;运算&#xff0c;但我们通常在卷积层中使用更加直观的计算方式&#xff0c;叫做互相关&#xff08; cross-correlation &#xff09;运算。 也就是说&#xff0c;其实我们现在在这里…

84 柱状图中的最大的矩形(单调栈)

题目 柱状图中的最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 …

使用python快速搭建接口自动化测试脚本实战总结

导读 本文将介绍如何使用python快速进行http/https接口自动化测试脚本搭建&#xff0c;实现自动请求、获取结果、数据对比分析&#xff0c;导出结果到Excel等功能&#xff0c;包括python的requests、pandas、openpyxl等库的基本使用方法。 测试需求介绍 通常&#xff0c;在我…

Node.js |(七)express案例实践:记账本 | 尚硅谷2023版Node.js零基础视频教程

文章目录 &#x1f4da;基本结构搭建&#x1f4da;响应静态网页&#x1f4da;获取表单数据&#x1f4da;借助lowdb保存账单信息&#x1f4da;完善成功提醒&#x1f4da;账单列表&#x1f4da;删除账单&#x1f4da;final 学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程…

git上传项目至github(Linux)

01 git版本创建 git init 创建版本库 创建一个版本 git add test1.cpp git commit -m 说明信息 git log 查看版本记录 02 版本回退 git reset --hard HEAD^ 版本回退一个 git reset --hard HEAD^^ 版本回退二个 git reset --hard 版本号 版本回退到指定版本&#xff0…

学习c++的第十三天

目录 文件和流 打开文件 关闭文件 写入文件 读取文件 读取 & 写入实例 文件位置指针 异常处理 扩展知识 抛出异常 标准的异常 定义新的异常 文件和流 到目前为止&#xff0c;我们已经使用了 iostream 标准库&#xff0c;它提供了 cin 和 cout 方法分别用于从标…