HarmonyOS鸿蒙Next中overlay属性浮层和LoadingProgress()组件结合使用,导致LoadingProgress动画停顿
HarmonyOS鸿蒙Next中overlay属性浮层和LoadingProgress()组件结合使用,导致LoadingProgress动画停顿 环境:Deveco Studio 6.0.0版本,“targetSdkVersion”: “6.0.0(20)”
根据最佳实践
中提到,使用overlay属性优化,减少嵌套组件数量
将如下代码中Stack组件优化掉
@ComponentV2
struct PrivacyPage {
// web组件是否加载中
@Local isWebLoading: boolean = true;
webViewController: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Stack() {
Web({
src: $rawfile('***.html'),
controller: this.webViewController,
})
.onPageBegin(() => {
this.isWebLoading = true
})
.onPageEnd(() => {
this.isWebLoading = false
})
LoadingProgress()
.width(60)
.height(60)
.enableLoading(this.isWebLoading)
}
.width('100%')
.height('100%')
}
.height('100%')
.width('100%')
.backgroundColor($r('sys.color.background_secondary'))
.padding(8)
}
}
优化结果
@ComponentV2
struct PrivacyPage {
// web组件是否加载中
@Local isWebLoading: boolean = true;
webViewController: webview.WebviewController = new webview.WebviewController();
@Builder
LoadingProgressOverlay() {
LoadingProgress()
.width(60)
.height(60)
.enableLoading(this.isWebLoading)
}
build() {
Column() {
Web({
src: $rawfile('***.html'),
controller: this.webViewController,
})
.onPageBegin(() => {
this.isWebLoading = true
})
.onPageEnd(() => {
this.isWebLoading = false
})
.width('100%')
.height('100%')
.overlay(this.LoadingProgressOverlay(), { align: Alignment.Center })
}
.height('100%')
.width('100%')
.backgroundColor($r('sys.color.background_secondary'))
.padding(8)
}
}
该优化结果会导致LoadingProgress的加载动画停顿,在当前API版本下是否有办法解决,或者有更好的优化方法?
更多关于HarmonyOS鸿蒙Next中overlay属性浮层和LoadingProgress()组件结合使用,导致LoadingProgress动画停顿的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者你好
参考LoadingProgress文档说明:加载动效在组件不可见时停止,组件的可见状态基于onVisibleAreaChange处理,可见阈值ratios大于0即视为可见状态。
因为overlay属性对应的Builder结构不会上树,不在组件树上,所以LoadingProgress组件一直处于不可见状态,而LoadingProgress在不可见时动画会停止,所以出现了动画不动的现象。
【解决方案】
开发者可以参考以下方案,将LoadingProgress组件挂载到overlayManager上,通过overlayManager打开或者关闭动画。
示例demo如下:
import { webview } from '@kit.ArkWeb';
import { ComponentContent } from '@kit.ArkUI';
@Builder
function LoadingProgressOverlay() {
LoadingProgress()
.width(60)
.height(60)
.enableLoading(true)
.onAppear(() => {
console.log('onAppear');
})
.onVisibleAreaChange([0, 0.5], (isExpanding, value) => {
console.log('', isExpanding, value);
})
}
@Entry
@ComponentV2
struct Index {
// web组件是否加载中
@Local isWebLoading: boolean = true;
webViewController: webview.WebviewController = new webview.WebviewController();
@Builder
LoadingProgressOverlay() {
LoadingProgress()
.width(60)
.height(60)
.enableLoading(this.isWebLoading)
.onAppear(() => {
console.log('', 'onAppear');
})
.onVisibleAreaChange([0, 0.5], (isExpanding, value) => {
console.log('', isExpanding, value);
})
}
build() {
Column() {
Web({
src: '',
controller: this.webViewController,
})
.onPageBegin(() => {
this.isWebLoading = true;
this.getUIContext().getOverlayManager().addComponentContent(new ComponentContent(this.getUIContext(), wrapBuilder(LoadingProgressOverlay)));
this.getUIContext().getOverlayManager().showAllComponentContents();
})
.onPageEnd(() => {
this.isWebLoading = false;
this.getUIContext().getOverlayManager().hideAllComponentContents();
})
.width('100%')
.height('100%')
}
.height('100%')
.width('100%')
.backgroundColor($r('sys.color.background_secondary'))
.padding(8)
}
}
更多关于HarmonyOS鸿蒙Next中overlay属性浮层和LoadingProgress()组件结合使用,导致LoadingProgress动画停顿的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,overlay属性创建的浮层与LoadingProgress组件结合使用时,可能导致动画停顿。这是因为overlay浮层可能阻塞了UI渲染线程,影响了LoadingProgress的动画流畅性。建议检查浮层的布局层级和渲染机制,确保动画组件能获得足够的渲染资源。
在HarmonyOS Next中,使用overlay属性结合LoadingProgress组件导致动画停顿,通常是因为overlay的浮层内容在状态更新时触发了不必要的重建。LoadingProgress的动画依赖于其内部状态的持续更新,而overlay中的@Builder方法在每次状态变化时会被重新调用,可能导致动画重置或卡顿。
解决方案:
-
使用
@BuilderParam延迟构建
将LoadingProgress的构建移至@BuilderParam,避免每次状态更新时重新创建整个浮层内容。示例:[@ComponentV2](/user/ComponentV2) struct PrivacyPage { @Local isWebLoading: boolean = true; webViewController: webview.WebviewController = new webview.WebviewController(); @BuilderParam overlayBuilder: () => void = this.loadingOverlay; @Builder loadingOverlay() { LoadingProgress() .width(60) .height(60) .enableLoading(this.isWebLoading) } build() { Column() { Web({ src: $rawfile('***.html'), controller: this.webViewController, }) .onPageBegin(() => { this.isWebLoading = true }) .onPageEnd(() => { this.isWebLoading = false }) .width('100%') .height('100%') .overlay(this.overlayBuilder, { align: Alignment.Center }) } // ... 其他样式 } } -
分离动画控制与状态更新
确保isWebLoading的状态变化不会触发overlay的完整重建。可以尝试将LoadingProgress的启用控制与浮层构建解耦,或使用@State修饰符配合条件渲染优化。 -
临时回退方案
若上述方法无效,可暂时保留Stack组件,避免使用overlay。虽然嵌套层级增加,但能保证动画流畅性。后续可关注HarmonyOS版本更新,该问题可能在API优化后解决。
根本原因:overlay的@Builder方法在每次isWebLoading变化时被重新执行,导致LoadingProgress实例重建,动画中断。建议优先采用@BuilderParam或检查状态更新链路,减少不必要的重建。

