从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?

抱着这样的疑问和对鸿蒙开发的好奇,让我们开始今天对ArkTS语言的了解以及对组件的掌握吧!

目录

初识ArkTS语言

ArkUI基础组件

Image(图片显示组件)

Text(文本显示组件)

TextInput(文本输入框)

Button(按钮组件)

Slider(滑动条组件)

Column、Row(布局容器)

ForEach(循环控制)

List(列表容器)

ArkTS自定义组件


初识ArkTS语言

ArkTS是HarmonyOS优选的主力应用开发语言,它在 TypeScript(简称TS) 的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。要了解什么是ArkTS,我们要先了解一下ArkTS、TypeScript 和 JavaScript 之间的关系,如下:

学习ArkTS之前还是推荐先了解并掌握一下 JSTS ,这两门语言的掌握再回头看ArkTS的话可谓是上手很快了。ArkTS兼容TypeScript语言,拓展了声明式UI、状态管理、并发任务等能力。在学习ArkTS语言之前,建议开发者具备ts语言的开发能力,当前ArkTS在ts的基础上主要扩展了如下能力:

基本语法

ArkTS定义了声明式 UI 描述、自定义组件和动态扩展UI元素的能力,再配ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共同构成了UI开发的主体。

状态管理:

ArkTS提供了多维度的状态管理机制。在UI开发框架中,与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递。开发者可以灵活的利用这些能力来实现数据和UI的联动。

渲染控制

ArkTS 提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

未来,ArkTS会结合应用开发/运行的需求持续演进,逐步提供并行和并发能力增强、系统类型增强、分布式开发范式等更多特性。

在ArkTS的布局结构方面,开发者需要在页面上声明对应的元素,其布局的结构通常是分层级的,代表了用户界面中的整体架构,一个常见的页面结构如下:

其中Page表示页面的根节点,Column/Row等元素为系统组件。针对不同的页面结构,ArkUI提供了不同的布局组件来帮助开发者实现对应布局的效果,例如Row用于实现线性布局等,我会给大家详细讲解对应的布局。

ArkUI基础组件

接下来将对ArkUI常用的基础组件进行一个简单的演示与应用,掌握ArkUI的基本使用。

Image(图片显示组件)

声明Image组件并设置图片源方式如下:

Image(src: string|PixelMap|Resource)

1)string格式,通常用来加载网络图片,需要申请网络访问权限:ohos.permission.INTERNET

Image('https://xxx.png')

打开 module.json5 文件夹下,配置如下 requestPermissions 选项,可以看到图片出现。

2)PixelMap格式,可以加载像素图,常用在图片编辑中

Image(pixelMapObject)

3)Resource格式,加载本地图片,推荐使用

Image($r('app.media.mate'60.png)

Image($rawfile('mate60.png'))

Text(文本显示组件)

Text(content?: string|Resource)

1)string格式,直接填写文本内容

Text('文本内容')

2)Resource格式,读取本地资源文件

Text($r('app.string.width_label'))

这里我们设置了一个动态的文本显示:

TextInput(文本输入框)

TextInput( {placeholder?: ResourceStr, text?: ResourceStr} )

1)placeHolder:输入框无输入时的提示文本

TextInput({placeholder: '请输入账号或手机号'})

2)text:输入框当前的文本内容

TextInput({text: '文本内容'})

比如我们用输入框动态的改变一个图片的大小操作如下:

下面是输入框的各种类型描述:

名称描述
Normal基本输入模式。支持输入数字、字母、下划线、空格、特殊字符。
Password密码输入模式。支持输入数字、字母、下划线、空格、特殊字符。
Email邮箱地址输入模式。支持数字,字母,下划线,以及@字符。
Number纯数字输入模式。
PhoneNumber电话号码输入模式。支持输入数字、+、-、*、#、长度不限。

Button(按钮组件)

Button(label?: ResourceStr)

1)文字型按钮

Button('点我')

2)自定义按钮,在Button内嵌套其它组件

Button(){

Image($r('app.media.search')).width(20).margin(10)

}

比如我们用按钮动态的改变一个图片的大小操作如下:

下面是按钮的各种类型描述:

名称描述
Capsule胶囊型按钮(圆角默认为高度的一半)。
Circle圆形按钮。
Normal普通按钮(默认不带圆角)。

Slider(滑动条组件)

滑动条的组件的功能实现很简单,只需要在Slider里面设置其功能,外部设置其样式即可:

Column、Row(布局容器)

Column容器与Row容器其对应的对齐方式使用的参数如下表格所示:

属性方法名说明参数
justifyContent设置子元素在主轴方向的对齐格式FlexAlign枚举
alignItems设置子元素在交叉轴方向的对齐格式Row容器使用VerticalAlign枚举
Column容器使用HorizontalAlign枚举

Column容器中使用FlexAlign的主轴对齐方式函数及其特点如下所示:

Row容器中使用FlexAlign的主轴对齐方式函数及其特点如下所示:

两者在交叉轴上的对齐方式如下所示:

Column容器:纵向布局,先从上往下,再从左往右。

Row容器:横向布局,先从左往右,再从上往下。

以下给出使用Column和Row容器的例子:

@Entry
@Component

struct Index {
  // 设置状态变量
  @State ImageWidth: number = 150

  build() {
    Column() {
      Row(){
        Image($r('app.media.icon'))
          .width(this.ImageWidth)
          .interpolation(ImageInterpolation.High)
      }
      .width('100%')
      .height(400)
      .justifyContent(FlexAlign.Center)
      Row(){
        Text($r('app.string.width_label'))
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#008c8c')
        TextInput({text: this.ImageWidth.toString()})
          .backgroundColor('#fff')
          .width(200)
          .type(InputType.Number) // 只能输入数字类型
          .onChange(value=>{
            if (!value) {
              this.ImageWidth = 0
            }else {
              this.ImageWidth = parseInt(value)
            }
          })
      }
      .width('100%')
      .padding({left: 10, right: 10})
      .justifyContent(FlexAlign.SpaceBetween)
      Divider().width('91%')
      Row(){
        Button('缩小')
          .width(80)
          .fontSize(20)
          .onClick(()=>{
            if(this.ImageWidth >= 10){
              this.ImageWidth -= 10
            }
          })
        Button('放大')
          .width(80)
          .fontSize(20)
          .onClick(() => {
            if (this.ImageWidth <= 300) {
              this.ImageWidth += 10
            }
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceAround)
      .margin({top: 30, bottom: 30})

      Slider({
        min: 100,
        max: 300,
        value: this.ImageWidth,
        step: 10, // 步长
      })
        .width('90%')
        .blockColor('#36D')
        .trackThickness(5) // 滑动条的粗细
        .showTips(true) // 显示气泡百分比
        .onChange(value => {
          this.ImageWidth = value
        })
    }
    .width('100%')
    .height('100%')
  }
}

呈现的效果如下所示:

ForEach(循环控制)

ForEach循环遍历数组,根据数组内容渲染页面组件,以下是其基本格式:

ForEach(
    arr: Array, // 要遍历的数据数组
    (item: any, index?: number) => {
        // 页面组件生成函数
    }
    keyGenerator?: (item: any, index?: number): string => {
        // 键生成函数,为数组每一项生产一个唯一标识,组件是否重新渲染的判断标准
    }
)

以下是通过ForEach生成页面的组件的基本案例:

class Item {
  name: string
  image: ResourceStr
  price: number
  discount: number

  constructor(name: string, image: ResourceStr, price: number, discount = 0) {
    this.name = name
    this.image = image
    this.price = price
    this.discount = discount
  }
}

@Entry
@Component

struct Index {
  // 商品数据
  private items: Array<Item> = [
    new Item('华为', $r('app.media.icon'), 6999, 500),
    new Item('小米', $r('app.media.icon'), 7999),
    new Item('苹果', $r('app.media.icon'), 9999),
    new Item('三星', $r('app.media.icon'), 3999),
    new Item('oppo', $r('app.media.icon'), 1999),

  ]
  build(){
    Column({space: 4}){
      Row(){
        Text('商品列表')
          .fontSize(30)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
      .margin({bottom: 20})

      ForEach(
        this.items,
        (item: Item) => {
          Row({space: 10}){
            Image(item.image)
              .width(100)
            Column({space: 4}){
              if (item.discount) {
                Text(item.name)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                Text('原价:¥ '+ item.price)
                  .fontColor('#ccc')
                  .fontSize(14)
                  .decoration({type: TextDecorationType.LineThrough})
                Text('折扣价:¥ '+ (item.price - item.discount))
                  .fontColor('#F36')
                  .fontSize(18)
                Text('补贴:¥ '+ item.discount)
                  .fontColor('#F36')
                  .fontSize(18)
              }else {
                Text(item.name)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                Text('¥ '+ item.price)
                  .fontColor('#F36')
                  .fontSize(18)
              }
            }
            .margin({left: 10})
            .height('100%')
            .alignItems(HorizontalAlign.Start)
          }
          .width('100%')
          .height(120)
          .borderRadius(20)
          .backgroundColor('#EFEFEF')
          .padding(20)
          .margin({bottom: 10})
        }
      )
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

呈现的结果如下所示:

List(列表容器)

List是一种复杂的容器,当页面内容数量过多超出屏幕后,其列表项ListItem会自动提供滚动功能,当然列表项既可以纵向排列也可以横向排列,其基本格式代码如下:

List({space: 10}){
    ForEach([1, 2, 3, 4], item => {
        ListItem(){
            // 列表项内容,只能包含一个根组件
            Text('ListItem')
        }
    })
}
.width('100%')
.listDirection(Axis.Vertical) // 列表方向,默认纵向(垂直)

在ForEarch外面我们嵌套一层List容器,在ForEach里面我们嵌套ListItem,来实现页面的滚动:

最终呈现的效果如下:

ArkTS自定义组件

ArtTS提供了一些自定义组件及函数的方式,让繁杂的代码抽离出来,便于代码的可维护性和可阅读性,增强了代码的健壮性,以下是ArkTS进行自定义组件等相关的方法:

自定义组件:自定义组件很简单,可以在一个ets中进行书写,将一部分代码处理出来新设置一个 struct 构造函数即可,也可以将代码单独抽离出来形成一个新的文件,如下将上面案例的头部组件抽离出来形成一个新的组件Header,然后再在原本书写头部代码的位置引用Header组件即可:

自定义函数:自定义函数可以将烦长的代码单独抽离出一个函数当中,然后在原位置调用我们设置的函数即可,自定义函数可以定义在全局或组件内,如下:

如果想设置组件内自定义函数,则需要设置与build()函数平级然后去掉function,然后引用函数的位置需要通过this指向即可:

@Styles装饰器: 用来设置组件公共样式,可以定义在全局或者组件内,和自定义函数的方式一致,如下:

@Extend装饰器:仅可定义在全局,用来设置组件的特有属性,使用方式与上面一致:

// 继承模式,只能写在全局
@Extend(Text) function priceText() {
  .fontSize(18)
  .fontColor('#F36')
}

相关文章

使用Go Validator在Go应用中有效验证数据

Go Validator是一个开源的包,为Go结构体提供强大且易于使用的数据验证功能。该库允许开发者为其数据结构定义自定义验证规则,并确保传入的数据满足指定的条件。Go Validator支持内置验证器、自定义验证器,甚至允许您链式多个验证规则以满足更复杂的数据验证需求。如果内置验证器无法满足您的需求,您可以通过定义自己的验证函数来创建自定义验证器。这个功能允许您实现特定于应用程序需求的验证逻辑。

C# this关键字的作用

关键字在C#中主要用于引用当前对象,区分字段与局部变量,调用其他构造函数以及传递当前对象给其他方法或构造函数。

C语言中关于#include的一些小知识

如果是你自己编写的头文件,那么如果没加唯一包含标识的话,那么编译器会编译报错的。如果是系统自带的头文件,由于其每个头文件都加了特殊标识,所以即使你包含两遍,也不会有问题。上面的代码片段会首先判断HEADER_FILE_NAME_H是否被定义,若未定义则进行后续操作;#ifndef HEADER_FILE_NAME_H // 定义了一个名为HEADER_FILE_NAME_H的标记符号。#define HEADER_FILE_NAME_H // 当第一次包含该头文件时,将此标记设置为已定义状态。

harmony 鸿蒙系统学习 安装ohpm报错 ohpm install failed

找原因,首先,通过查看文件,先看软件的使用node的配置,发现config用的是 .npmrc文件,去c盘找到对应文件打开看看。确实是,这里的镜像不对。(网上很多攻略要求你卸载以前的node或者卸载这个刚安装的软件,再重装,其实不需要这么麻烦。)

C语言中的作用域与生命周期

但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在自己所在的源文件内部使用了,其他源文件,即使声明了,也是无法正常使用的。结论:static修饰局部变量改变了变量的生命周期,生命周期改变的本质是改变了变量的存储类型,本来一个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。extern 是用来声明外部符号的,如果一个全局的符号在A文件中定义的,在B文件中想使用,就可以使用extern进行声明,然后使用。全局变量的生命周期是:整个程序的生命周期。

Python和Java的区别(不断更新)

运行效率:一般来说,Java的运行效率要高于Python,这主要是因为Java是编译型语言,其代码在执行前会进行预编译,而Python是解释型语言,边解释边执行。而Python没有类似的强大虚拟机,但它的核心是可以很方便地使用C语言函数或C++库,这使得Python可以轻松地与底层硬件进行交互。**类型系统:**Java是一种静态类型语言,所有变量需要先声明(类型)才能使用,且类型在编译时就已经确定。总的来说,Python和Java各有其优势和特点,选择哪种语言取决于具体的项目需求、开发环境以及个人偏好。

C#中的浅度和深度复制(C#如何复制一个对象)

接着,我们修改了复制得到的对象及其引用类型字段的属性值,最后输出原始对象和复制对象的属性值。这意味着如果一个类包含引用类型成员,在执行深度复制时,不仅复制这些引用,还会递归地复制引用所指向的对象,直到所有的引用都指向全新的对象实例。当进行浅复制时,系统会创建一个新的对象实例,但这个新对象的字段将与原始对象中的值类型字段具有相同的值,而对于引用类型字段,则仅仅是复制了。也就是说,如果一个类中有引用类型的成员变量(比如数组、其他自定义类的对象等),那么浅复制后,新对象和原对象的这些引用类型成员仍然指向。

C++ STL精通之旅:向量、集合与映射等容器详解

STL 作为一个封装良好,性能合格的 C++ 标准库,在算法竞赛中运用极其常见。灵活且正确使用 STL 可以节省非常多解题时间,这一点不仅是由于可以直接调用,还是因为它封装良好,可以让代码的可读性变高,解题思路更清晰,调试过程往往更顺利。

HarmonyOS应用开发者基础认证考试答案

B. 通过&quot;$r(‘app.type.name’)&quot;的形式引用应用资源,app代表是应用内resources目录中定义的资源,type代表资源类型(或资源的存放位置)。5.在Column和Row容器组件中,justifyContent用于设置子组件在主轴方向上的对齐格式,alignItems用于设置子组件在交叉轴方向上的对齐格式。E. 属性方法:用于组件属性的配置,统一通过属性方法进行设置,如fontSize()、width()、height()、color() 等。

解决Linux环境下gdal报错:ERROR 4: `/xxx.hdf‘ not recognized as a supported file format.

题外话:我发现linux系统和Windows系统下面,库的版本是有差异的。比如我的本机Windows上装的是gdal3.2.3和numpy1.19.1,linux服务器上装的却是gdal3.0.2和numpy1.21.5。这个是很常见的回复,网上许多回答都说低版本的 gdal 不支持 hdf5,让你重装高版本的gdal。我之前用pip安装了whl,暴力装上了,但用的时候就会有问题。安装了不冲突的gdal之后,就成功打开文件啦~一开始我是抱着试试的心态,用conda,不用pip,重新安装了一下我的gdal。

C语言常见面试题:什么是枚举,枚举的作用是什么?

首先,枚举是一种特殊的类,它的主要作用是封装一组常量,例如,一周的七天、月份、季节等。枚举在JDK1.5后被引入,相较于之前的常量定义方式,枚举具有更好的安全性和更好的性能。每个枚举常量都是该枚举类的一个实例,因此可以使用构造函数来初始化每个枚举常量的值。综上所述,枚举的常用用法包括常量定义、switch语句、添加新方法、覆盖枚举的方法、实现接口以及使用接口组织枚举等。枚举是一种特殊的数据类型,它是一组具命名的整型常量的集合。枚举是一种特殊的数据类型,它是一组具命名的整型常量的集合。

为什么Java中的String类被设计为final类?

String类作为Java中不可或缺的类之一,被设计成final类带来了不可变性、安全性、可靠性和性能优势。不可变的特性使得String对象在多线程环境下安全共享,提高了应用程序的并发性和性能。此外,String类的设计还符合Java类库的一致性和规范,确保了整个语言的稳定性和可靠性。因此,String类被设计成final类是出于多方面的考虑,以提供最佳的使用体验和编程效率。

鸿蒙(ArkUI)开发:实现二级联动

列表的二级联动(Cascading List)是指根据一个列表(一级列表)的选择结果,来更新另一个列表(二级列表)的选项。这种联动可以使用户根据实际需求,快速定位到想要的选项,提高交互体验。例如,短视频中拍摄风格的选择、照片编辑时的场景的选择,本文即为大家介绍如何开发二级联动。

HarmonyOS 页面page间元素转场动画

这里 id我们还写没写 然后 第二个参数 我们设置 动画 2000毫秒 就是两秒执行完。但是 目前 我们跳转是没有什么动画 看不出什么特别明显的动态效果的。我们可以给第一个 和第二个界面 image图片组件都加上如下代码。然后 还有一个问题 我们需要的是 这个图片一个慢慢变大的效果。此时 我们点击图片 它就会跳到我们 AppView 来了。第二个 是我们属性的 json 类型的动画配置参数。我们第二个界面的 image组件也要对应加上。这里 我们写的基本和第一个界面一模一样的结构。

HarmonyOS4.0系统性深入开发19进程模型概述

HarmonyOS通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力。公共事件从系统角度可分为:系统公共事件和自定义公共事件。系统公共事件:CES内部定义的公共事件,只有系统应用和系统服务才能发布,例如HAP安装,更新,卸载等公共事件。目前支持的系统公共事件详见系统公共事件列表。自定义公共事件:应用自定义一些公共事件用来实现跨进程的事件通信能力。公共事件按发送方式可分为:无序公共事件、有序公共事件和粘性公共事件。

Promise和箭头函数和普通函数的区别

箭头函数与普通函数的区别在于: 1、箭头函数没有this,所以需要通过查找作用域链来确定this的值,这就意味着如果箭头函数被非箭头函数包含,this绑定的就是最近一层非箭头函数的this, 2、箭头函数没有自己的arguments对象,但是可以访问外围函数的arguments对象 3、不能通过new关键字调用,同样也没有new.target值和原型。6、箭头函数没有自己的arguments,可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表。

ElasticSearch 集群搭建与状态监控cerebro

在单机上利用docker容器运行多个es实例来模拟es集群。部署es集群可以直接使用docker-compose来完成,但要求Linux虚拟机至少有4GI的内存空间。&quot;number_of_replicas&quot;: 1 // 副本数。&quot;number_of_shards&quot;: 3,// 分片款量。kibana可以监控es集群,不过新版本需要依赖es的x-pack 功能,配置比较复杂。第一种方式:利用kibana的DevTools创建索引库 ,在DevTools中输入指令。第二种方式:利用cerebro创建索引库。

【HarmonyOS】深入了解 ArkUI 的动画交互以提高用户体验

从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?抱着这样的疑问和对鸿蒙开发的好奇,让我们开始今天对ArkUI动画操作的掌握吧!

【HarmonyOS】鸿蒙开发简介与项目基础配置演示

从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是什么?鸿蒙仅仅是一个手机操作系统吗?它的出现能够和Android和IOS三分天下吗?它未来的潜力能否制霸整个手机市场呢?

SpringMVC之获取请求参数和域对象共享数据

一、SpringMVC获取请求参数1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数6、通过POJO获取请求参数7、解决获取请求参数的乱码问题二、域对象共享数据1、使用ServletAPI向request域对象共享数据2、使用ModelAndView向request域对象共享数据3、使用Model向request域对象共享数据4、使用map向request域对象共享数据5、使用ModelMap向request域对象共享数据。
返回
顶部