今天学ImageAnimator、ArkTS 语法进阶
一、ImageAnimator
1.1 作用
提供逐帧播放的能力
1.2 基本语法
ImageAnimator()
.属性()
1.3 常用属性
| 参数 | 类型 |
|---|---|
| images | Array |
| 描述 | |
|---|---|
| 设置图片帧集合 |
| state | Animationstate |
| 用于控制播放状态,默认初始状态 |
| duration | number |
| 一张图片的播放时间 | 单位:毫秒。默认值:1000 |
| iterations | number |
| 控制播放次数 | 默认一次。-1:无限循环 |
更多属性参考文档...
小案例
实现如下效果
参考代码:
@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 别名 = 类型
// 后续直接使用别名即可
小案例
示例代码:
// 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 父类{
// 自己的字段(属性)
// 自己的方法
// 可以重写父类方法
}
小案例
// 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 方法(){}
}
// 使用
类.字段
类.方法()
小案例
// 定义一个工具类
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
小案例
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,...剩余参数数组){
// 逻辑代码
// 剩余参数之前的参数 挨个获取即可
// 剩余参数:以数组的形式获取
}
小案例
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
这两类数据在内存中保存方式不一样,导致它们的赋值结果有区别。
比如下面的例子:
- numA和 numB 的值分别是?
- 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、 堆:存储容量大,存放引用数据类型
基本类型数据是如何保存的呢?
4.1.1 基本数据类型存储
变量的数据类型直接存放在栈中,访问速度快。
4.1.2 引用数据类型存储
1、栈空间:存放变量的内存地址(堆中的地址)
2、堆空间:存放变量的数据
思考:
通过索引,修改上图中 numArr 某一项的值,改的是哪里的数据?
答:改的是堆中的数据
4.2 站在内存角度看赋值
4.2.1 基本数据类型
num1 num2 都保存在栈内存中,虽然值相同,但是各自是独立的空间,后续操作互不影响。
let num1:number = 10
let num2:number = num1
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'
今天的学习就到这,希望能帮助大家。