arkTs:使用setTimeout / setInterval 实现透明度切换的轮播图
使用setTimeout / setInterval 实现透明度切换的轮播图
- 1 主要内容说明
- 1.1 setTimeout
- 1.2 setInterval
- 1.3 表格
- 2 举例说明
- 2.1 图片变化的内容说明
- 2.2 源码相关内容说明
- 2.3 源码A
- 2.4源码A的运行效果展示
- 2.4.1 效果截图
- 2.4.2 效果视频
- 3.结语
- 4.定位日期
1 主要内容说明
1.1 setTimeout
- 作用:延迟执行一次函数。
- 语法:
setTimeout(callback, delay)
- 特点:
只执行一次。
常用于“延迟执行”或“递归实现定时效果”。
可以通过 clearTimeout(timerId) 取消。 - 适用场景:
想要某段逻辑延时执行一次。
递归实现更灵活的“每次都延迟”的轮播或动画(如后面代码中的 autoSliderWithTimeout())。
1.2 setInterval
-
作用:每隔一定时间重复执行函数。
-
语法:
setInterval(callback, interval)
-
特点:
会无限循环,直到使用 clearInterval(timerId) 停止。
时间间隔不保证精准,受函数执行时间影响。 -
适用场景:固定时间循环执行任务,如轮播、时钟、轮询等。
1.3 表格
特性 | setTimeout | setInterval |
---|---|---|
执行次数 | 一次 | 无限循环 |
控制灵活性 | 高(适合递归控制) | 较低(固定节奏) |
可用于动画控制 | 可以 | 可以 |
中断方式 | clearTimeout(id) | clearInterval(id) |
精准性 | 更容易避免积压 | 有可能出现时间漂移 |
2 举例说明
2.1 图片变化的内容说明
我们根据索引的单周期indexNum: number = 0 // 总切换次数(用于计算当前显示的图片索引)
+1的情况,整除数组的长度,可以循环的按顺序显示使用数组的元素。这里我们需要两个对象显示索引,这里我们选为图1和图2,图1为要消失的索引,图2为要生成的索引。
我们对于图片,想要达到图片虚化切换图片的效果,只需要使前图的透明度是由1到0变换,后图的透明度是由0到1的变换,也就是说前图它是逐渐消失,后图他是逐渐出现,两图结合可达到图片视图虚化切换的效果。
这里使用animation的动画效果,同个图片,要设置两种状态,透明度为1的状态,到透明度为0的状态,当前周期变换到下个周期时,状态进行变换。
以下是几个周期的数据内容===>数据内容 图1索引:1 图2索引:2 前图透明度:0 后图透明度:1===>数据内容 图1索引:2 图2索引:3 前图透明度:1 后图透明度:0===>数据内容 图1索引:3 图2索引:4 前图透明度:0 后图透明度:1===>数据内容 图1索引:4 图2索引:0 前图透明度:1 后图透明度:0===>数据内容 图1索引:0 图2索引:1 前图透明度:0 后图透明度:1===>数据内容 图1索引:1 图2索引:2 前图透明度:1 后图透明度:0===>数据内容 图1索引:2 图2索引:3 前图透明度:0 后图透明度:1
通过上面几组单周期的显示内容数据,不难看出,透明度是由0到1,再由1到0的周期性变换,我们需要控制图2必须是出现的,也就是必须为0到1的变换状态;图1则必须是消失的,也就是1到0的变换状态。
根据透明度的周期性变换,当前图的透明度变换是0到1,那么这个周期变化到下个周期,图片是是出现的,那么就需要保证这个前图显示图2的索引对象。此时后图的透明度是1到0,与前图相反,这个周期变换到下个周期,图片是消失的,则此时后图的显示需要使用图1索引对象上。
到下一轮后,前图的透明度变换是1到0,那么它是消失的,则显示的对象应为图1的索引对象。后图的透明度变换为0到1,那么它是出现的,则显示的对象应为图2的索引对象。
2.2 源码相关内容说明
这段代码是一个图片淡入淡出轮播组件,用来实现两张图片在 UI 上交替显示的效果。图片切换通过 setTimeout 或 setInterval 实现,配合 opacity 和 animation 做视觉过渡。
-
轮播结构设计
使用 Stack 堆叠两张图片,通过透明度控制前后图的显示与隐藏。
切换时前图从 1 → 0(淡出),后图从 0 → 1(淡入)。 -
索引轮换逻辑:
每次切换 indexNum++,根据数组长度取余,计算当前显示图(图1)和下一张图(图2)的索引。
通过 isSwitchover 控制谁是前图、谁是后图。 -
定时器方式:提供了 setInterval 和 setTimeout 两种方式。
setInterval:
固定每 4 秒切换。
setTimeout:
递归延时,保证上一轮动画执行完再进行下一轮。 -
动画过渡处理:
两张图的透明度在 [0,1] 间循环变换,配合 animation 实现柔和过渡效果。
2.3 源码A
/*** 图片淡入淡出轮播切换组件*/@Entry
@Component
struct Index {isSwitchover: boolean = false // 当前是否处于切换状态(用于判断哪一张图在前)indexNum: number = 0 // 总切换次数(用于计算当前显示的图片索引)@State indexFirst: number = 0 // 当前显示的图片索引@State indexSecond: number = this.indexFirst + 1 // 下一张图片的索引// 轮播图资源列表 图片资源可执行选择,也可以使用网络上的图片showMessage: ImageSwitchover[] = [{ imageUrl: $r("app.media.shui") },{ imageUrl: $r("app.media.xiaowoniu") },{ imageUrl: $r("app.media.xueren") },{ imageUrl: $r("app.media.lv_ye2") },{ imageUrl: $r("app.media.lv_ye") }]@State beforeImageOpacity: number = 1 // 当前前景图的透明度(初始为完全显示)@State backgroundImageOpacity: number = 0 // 当前背景图的透明度(初始为隐藏)timer: number = -1 // 定时器控制句柄// 页面加载完成后启动定时器aboutToAppear(): void {// this.autoSliderWithInterval()// 使用setInterval的方法this.autoSliderWithTimeout()// 使用setTimeout的方法}// 页面销毁时停止轮播aboutToDisappear(): void {clearInterval(this.timer)clearTimeout(this.timer)}build() {/*** 渲染逻辑说明:* - 每次切换涉及两张图,一张淡出(透明度从1变0),一张淡入(透明度从0变1)* - 通过 isSwitchover 控制谁是前图,谁是后图,从而形成无缝的轮播视觉* - 利用 Stack 重叠两张图,控制 opacity + animation 实现渐变过渡效果*/Stack({ alignContent: Alignment.Center }) {// 前图(透明度为1则显示,为0则隐藏)Image(this.isSwitchover ? this.showMessage[this.indexFirst].imageUrl :this.showMessage[this.indexSecond].imageUrl).width("100%").aspectRatio(1.68).borderRadius(8).opacity(this.beforeImageOpacity).animation({ duration: 2000, curve: Curve.Ease })// 后图(透明度为0则隐藏,为1则显示)Image(this.isSwitchover ? this.showMessage[this.indexSecond].imageUrl :this.showMessage[this.indexFirst].imageUrl).width("100%").aspectRatio(1.68).borderRadius(8).opacity(this.backgroundImageOpacity).animation({ duration: 2000, curve: Curve.Ease })}.width("100%").padding({ left: "5%", right: "5%" }).height("100%")}/*** 轮播图* 使用interval*/autoSliderWithInterval(){this.indexNum = 0 // 重置总次数this.timer = setInterval(() => {this.indexNum++ // 每次切换+1// 当前和下一张图的索引(循环取值)this.indexFirst = this.indexNum % this.showMessage.lengththis.indexSecond = (this.indexNum + 1) % this.showMessage.length// 控制透明度 1↔0 切换,用于触发淡入淡出动画this.beforeImageOpacity = this.beforeImageOpacity === 0 ? 1 : 0this.backgroundImageOpacity = this.backgroundImageOpacity === 0 ? 1 : 0// 切换当前前后图状态,用于决定谁是“图1”,谁是“图2”this.isSwitchover = !this.isSwitchoverconsole.log("===>轮播信息","图1索引:" + this.indexFirst +" 图2索引:" + this.indexSecond +" 前图透明度:" + this.beforeImageOpacity +" 后图透明度:" + this.backgroundImageOpacity)}, 4000) // 每4秒自动切换}/*** 轮播图* 使用Timeout*/autoSliderWithTimeout() {this.indexNum = 0const loop = () => {this.indexNum++this.indexFirst = this.indexNum % this.showMessage.lengththis.indexSecond = (this.indexNum + 1) % this.showMessage.lengththis.beforeImageOpacity = this.beforeImageOpacity === 0 ? 1 : 0this.backgroundImageOpacity = this.backgroundImageOpacity === 0 ? 1 : 0this.isSwitchover = !this.isSwitchoverconsole.log("setTimeout 轮播中:图1", this.indexFirst, "图2", this.indexSecond)// 下一轮递归调用this.timer = setTimeout(loop, 4000)}loop()}}// 图片数据结构
export interface ImageSwitchover {text1?: string // 图片上方说明文字(可选)text2?: string // 图片下方说明文字(可选)imageUrl: ResourceStr // 图片路径
}
2.4源码A的运行效果展示
2.4.1 效果截图
- 图片虚化样式的切换,截图效果没那么明显,视频效果观赏性更佳。
2.4.2 效果视频
图片淡入淡出轮播图
3.结语
对于计时器setTimeout和setInterval,由于老是忘记怎么拼写使用,又容易弄混,此次便专门的写一篇这相关的博文。加上前不久写过的图片虚化变换的例子时,想到例子里面的条条框框非常绕脑,这次就再重新给这个例子理一遍,加深记忆,也方便后期快速拿起使用。
暂时未在华为官方网站那找到相关的参考。此篇暂不设置参考指南超链接。
由于笔者的能力有限,创作的内容有所不足在所难免,也敬请读者包涵和指出,万分感谢!
4.定位日期
2025-4-19;
18:25;