HarmonyOS——每日一学

148 阅读7分钟

今天学ImageAnimator、ArkTS 语法进阶

一、ImageAnimator

1.1 作用

提供逐帧播放的能力

1.2 基本语法

ImageAnimator()
.属性()

1.3 常用属性

参数类型
imagesArray
描述
设置图片帧集合
stateAnimationstate
用于控制播放状态,默认初始状态
durationnumber
一张图片的播放时间单位:毫秒。默认值:1000
iterationsnumber
控制播放次数默认一次。-1:无限循环

更多属性参考文档...

小案例

实现如下效果

动画.gif

参考代码:

@Entry
@Component
struct Index {
 @State   state:AnimationStatus=AnimationStatus.Initial
 build() {
   Column(){
     //注意:当图片很多且很大时,要让美工处理它到最小值,且是保证高清的最小值
     ImageAnimator()
       //images必须能要给它宽高才能让图片出来
       .images([
         {src:$r('app.media.loading_dog_0')},
         {src:$r('app.media.loading_dog_1')},
         {src:$r('app.media.loading_dog_2')},
         {src:$r('app.media.loading_dog_3')},
       ])
       .width('100%')
       .height(200)
       .duration(1000)
       .iterations(-1)
       .state(this.state)
       Row(){
       Button('启动')
         .onClick(()=>{
           this.state=AnimationStatus.Running
         })
         Button('暂停')
           .onClick(()=>{
             this.state=AnimationStatus.Paused
             //暂停是停在这一帧
           })
         Button('停止')
           .onClick(()=>{
             this.state=AnimationStatus.Stopped
             //停止是返回第一帧
           })
       }
   }
   .width('100%')
   .height('100%')
   .backgroundColor(Color.Pink)
 }
}

二 、ArkTS 语法进阶

2.1 类型别名

作用

给某个类型起别名,之后就可以通过这个别名来使用类型啦

基本语法

代码如下:

    type 别名 = 类型
    // 后续直接使用别名即可
小案例

image.png 示例代码:

   // 1. 定义了一个类型别名Length1
type Length1 = number | string

// 2. 使用类型别名定义变量的类型即可
let w1:Length1 = '100%'// ✔️
let w2:Length1 = 100  // ✔️
// let w3:Length1 = true //❌

@Entry
@Component
struct Index {

 build() {
   Column() {

   }
   // .backgroundColor()
   .height('100%')
   .width('100%')

 }
}

2.2 类

作用:

类是用于创建对象的模板。他们用代码封装数据以处理数据。同时类声明也会引入一个新类型,并定义其字段,方法和构造函数。

基本语法
// 类名 首字母大写(规范)
class 类名{
// 属性
  
  

// 构造函数
  
  
// 方法  
}


// 使用类 实例化对象 基于类 创建对象
const x:类名 = new 类名()
  
2.2.1 实例属性
作用:

保证各种类型的数据。

基本语法:
// 类
class 类名{
// 字段名+类型+初始值
字段名:类型='xxx'
// 可选字段可以不设置初始值
字段名?:类型
}

小案例:创建一个对象,有名字和年龄
示例代码:
class   dy{
 name:string='dy'
 age:number=18
}

let   futuredy:dy=new  dy()
console.log(futuredy.name,futuredy.age)
   
2.2.2 构造函数
作用:

一个类中一旦有了显式编写 constructor, 在new 类()的时候是可以传参的

基本语法:
class 类{
字段A:类型
字段B:类型

constructor(参数...) {
  // 通过 new 实例化的时候 会调用 constructor
  // 通过关键字 this 可以获取到实例对象
}
}
const 实例 = new 类()
  
小案例:创建一个对象,有名字和年龄
示例代码:
class dy1 {
name: string
age: number

constructor(n: string, a: number) {
 this.name = n
 this.age = a
}
}

let fudy: dy1 = new dy1('刘诗诗', 18)
console.log(fudy.name, fudy.age)
2.2.3 实例方法
作用:

类中可以定义方法,并且在内部编写逻辑。

基本语法:
 class 类名{
  方法名(参数...):返回值类型{
    // 逻辑...
    // 可以通过 this 获取实例对象
  }
}
小案例:创建一个对象,有名字,年龄,有动作
class dy2 {
  name: string
  age: number

  constructor(n: string, a: number) {
    this.name = n
    this.age = a
  }

  dz1() {
    console.log('跳舞')
  }

  dz2(songname: string) {
    console.log('唱歌:', songname)
  }
}
console.log(fudy2.name,fudy2.age)
fudy2.dz2('aaa')
fudy2.dz1()
2.2.4 继承
作用:

类可以通过继承快速获取另外一个类的字段和方法,并且还可以扩展属于自己的字段和方法,加强父类没有的能力。

基本语法
class 父类{
    //字段
    //构造函数
    //方法
}

class 子类 extends 父类{
    // 自己的字段(属性)
  // 自己的方法
  // 可以重写父类方法
}
    
小案例

image.png

// 1. 父类 - 人
class Person {
  // 实例属性(字段)
  name: string
  age: number

  // 构造函数
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  // 实例方法
  sayHi() {
    console.log('说话')
  }
}

// 2. 子类 - 学生 继承了父类人
class Student extends Person {
  classesNo: string

  constructor(name: string, age: number, classesNo: string) {
    super(name, age)  // ✨✨super调用父类的构造函数进行父类中的实例属性初始化,只能写在子类的constructor中的第一行
    // super()
    this.classesNo = classesNo
  }

  // 由于这个方法父类中没有学习这个方法,所以是扩展的方法
  Len() {
    super.sayHi()
    // super.name // 获取到的是undefined 请使用this
    console.log(this.name + '学习')
  }
}

// 类中的this指向的是 new 出来的类的对象实例
let p: Student = new Student('明明', 22,'鸿蒙2期')
console.log(p.name , p.age,p.Len())
2.2.4 静态属性和方法
基本语法
 // 定义
class 类{
  static 字段:类型
  static 方法(){}
}

// 使用
类.字段
类.方法()
小案例

image.png

// 定义一个工具类
class Tools {
  // 静态的属性
  static PI:number = 3.1415926
  static getRandom() {
    return Math.random()
  }
}

// 使用
console.log(Tools.PI.toString())
console.log(Tools.getRandom().toString())

2.2.5 instanceof
作用:

instanceof 运算符可以用来检测某个对象是否是某个类的实例。

基本语法
// 返回判断结果 布尔值
实例对象 instanceof Class
小案例

image.png

class Person {
  name: string = ''
}

class Student extends Person {
  age: number

  constructor(age: number) {
    super()
    this.age = age
  }
}

const s = new Student(10)
console.log('isStudent', s instanceof Student)
console.log('isPerson', s instanceof Person)
console.log('isArray', [1, 2, 3,] instanceof Array)

const arr = [1, 2, 3]
// 等同于
const arr2 = new Array(1, 2, 3)
2.2.6 typeof 运算符
作用:

可以通过 typeof 运算符来获取类型,他返回的是一个字符串。

基本语法:
 // 后面跟上需要获取类型的 数据或变量 即可
typeof 表达式  -> 返回一个类型字符串
小案例:

依次获取 number、string、boolean、undefined、function 的类型

 // 前面 5 个可以正常获取到类型
console.log(typeof 123) // number
console.log(typeof '123') // string
console.log(typeof false) // boolean
console.log(typeof undefined) // undefined

function func() {
}

console.log(typeof func) // function

class Person {
  name: string = 'jack'
}

// 注意:对象 数组 null 获取到的都是 object

三、剩余和展开。

3.1 剩余参数

作用:

通过剩余参数的语法,我们可以将函数或方法中一个不定数量的参数表示为一个数组。

基本语法
// 剩余参数只能写在最后一位
function 函数名(参数1,参数2,...剩余参数数组){
 // 逻辑代码
 // 剩余参数之前的参数 挨个获取即可
 // 剩余参数:以数组的形式获取
}
小案例

image.png

function sum(numA:number,numB:number,...theArgs:number[]) {
  let total = numA+numbB;
  for (const arg of theArgs) {
    total += arg;
  }
  return total;
}

console.log(sum(1, 2, 3).toString()) // 6

console.log(sum(1, 2, 3, 4).toString()) // 10

3.2 展开函数

作用:

日常开发中,常用于进行数组的合并

小案例
const numArr1: number[] = [1, 2, 3, 4]
const numArr2: number[] = [5, 6, 7]

// 合并到一起
const totalArr: number[] = [...numArr1, ...numArr2]
    

四、 简单类型和复杂类型

ArkTS中的数据类型整体可以分为两大类:

1、基本数据类型(简单数据类型)

number 数字型、string 字符串型、boolean布尔型、undefined未定义、null空类型

2、引用数据类型(复杂数据类型)

Object、Function、Array

这两类数据在内存中保存方式不一样,导致它们的赋值结果有区别。

比如下面的例子:

  1. numA和 numB 的值分别是?
  2. p1.name和p2.name 分别是?
//基本数据类型
 let numA:number = 10
 let numB:number = numA
 numB++
 console.log('',numA)   //  10
 console.log('',numB)   //  11
 
//引用数据类型
 class  person{
 name:string=''
 }
  
const p1:person =  new person('jack')
const p2:person =  p1
p2.name = 'rose'
console.log(p1.name)  //  rose
console.log(p2.name)  //  rose

为了搞清楚上述现象的原因,就需要知道这两种数据内存存储的差异是什么?

4.1 内存中堆栈空间

我们可以把内存理解为两类空间

1、 栈:访问速度快,存放基本数据类型

2、 堆:存储容量大,存放引用数据类型

image.png

基本类型数据是如何保存的呢?

4.1.1 基本数据类型存储

变量的数据类型直接存放在栈中,访问速度快。

image.png

4.1.2 引用数据类型存储

1、栈空间:存放变量的内存地址(堆中的地址)

2、堆空间:存放变量的数据

image.png

思考:

通过索引,修改上图中 numArr 某一项的值,改的是哪里的数据?

答:改的是堆中的数据

4.2 站在内存角度看赋值

4.2.1 基本数据类型

num1 num2 都保存在栈内存中,虽然值相同,但是各自是独立的空间,后续操作互不影响。

 let  num1:number = 10
 let  num2:number = num1

image.png

4.2.2 引用数据类型

p1和p2栈内存中有各自独立的空间,但是保存的是堆内存的地址,指向的是同一个数据:

修改p2.name ,p1.name也会受到影响,因为是同一份数据。

class Person {
  name: string = ''
  constructor(name: string) {
    this.name = name
  }
}

const p1: Person = new Person('jack')
const p2: Person = p1
p2.name = 'rose'

image.png

今天的学习就到这,希望能帮助大家。