HarmonyOS 鸿蒙Next全局loading弹窗方法封装-自定义展示loading动画
HarmonyOS 鸿蒙Next全局loading弹窗方法封装-自定义展示loading动画
<markdown _ngcontent-dht-c237="" class="markdownPreContainer">
在之前预览版本只能通过子窗口的形式来封装全局loading弹窗,还要使用到缓存,这就不符合我们的本意了,6月22号升级到beta1之后看了下文档可以通过getUIContext来进行弹窗展示了,下面就展示封装的方法
先引入ComponentContent,window,PromptAction,用于创建弹窗,AnyType是我自定义的ts的any类型,在ets引入ts,ts里声明一个AnyTypt为any
import { AnyType } from '[@common](/user/common)/types';
import { ComponentContent, window, PromptAction} from '@kit.ArkUI';
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
先创建一个loading动画组件,这个是我自定义的loading动画,也可以自行修改组件,定义自己喜欢的loading动画效果,API12多了一个onDidBuild生命周期,可以在组件加载后调用动画。
[@Extend](/user/Extend)(GridItem) function loadingIconItem(){
.width('20lpx')
.height('20lpx')
.borderRadius('10lpx')
}
[@Component](/user/Component)
struct LoadingAnimation{
[@State](/user/State) rotateAngle:number = 0
build() {
Grid(){
GridItem()
.backgroundColor('#6F94B3')
.loadingIconItem()
GridItem()
.backgroundColor(<span class="hljs-string"><span class="hljs-string">'#0F4C81'</span></span>)
.loadingIconItem()
GridItem()
.backgroundColor(<span class="hljs-string"><span class="hljs-string">'#B7C9D9'</span></span>)
.loadingIconItem()
GridItem()
.backgroundColor(<span class="hljs-string"><span class="hljs-string">'#6F94B3'</span></span>)
.loadingIconItem()
}
.rotate({
x:<span class="hljs-number"><span class="hljs-number">0</span></span>,
y:<span class="hljs-number"><span class="hljs-number">0</span></span>,
z:<span class="hljs-number"><span class="hljs-number">1</span></span>,
centerX: <span class="hljs-string"><span class="hljs-string">'50%'</span></span>,
centerY: <span class="hljs-string"><span class="hljs-string">'50%'</span></span>,
angle:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.rotateAngle,
})
.width(<span class="hljs-string"><span class="hljs-string">'60lpx'</span></span>)
.height(<span class="hljs-string"><span class="hljs-string">'60lpx'</span></span>)
.columnsTemplate(<span class="hljs-string"><span class="hljs-string">'1fr 1fr'</span></span>)
.rowsTemplate(<span class="hljs-string"><span class="hljs-string">'1fr 1fr'</span></span>)
}
onDidBuild(): void {
animateTo({
duration: 1000,
curve: Curve.Linear,
iterations: -1,
}, () => {
this.rotateAngle = 360
})
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
然后再创建一个Builder,用于我们之后使用warpBuilder方法来定义全局Builder
class Params {
text: string = ""
constructor(text: string) {
this.text = text;
}
}
[@Builder](/user/Builder)
function loadingBuilder(params:Params){
Column({space:'26lpx'}){
LoadingAnimation()
Text(params.text)
.fontColor('#666666')
.fontSize('24lpx')
}
.width('200lpx')
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
下面就是主菜了,定义了一个Loading类,定义show方法和hide方法
class Loading{
private static loadingDialog:ComponentContent<AnyType> | null = null
private static promptAction:PromptAction
show(text:string = '加载中...'){
window.getLastWindow(getContext()).then((windowClass)=>{
const uiContext = windowClass.getUIContext()
Loading.loadingDialog = new ComponentContent(uiContext, wrapBuilder(loadingBuilder),new Params(text));
Loading.promptAction = uiContext.getPromptAction()
Loading.promptAction.openCustomDialog(Loading.loadingDialog,
{
alignment:DialogAlignment.Center,
isModal:true,
autoCancel:false
}
)
<span class="hljs-comment"><span class="hljs-comment">// const component = uiContext.getComponentUtils()</span></span>
})
}
hide(){
Loading.promptAction.closeCustomDialog(Loading.loadingDialog)
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
最后导出
export new Loading()
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
这个方法不止可以封装全局loading,也可以以一样的方法封装全局弹窗 ,toast等方法,目前官方文档似乎也没有自定义展示图片的toast,不过用这个方法我们就可以完全自定义弹窗展示了,而不用去封装组件每个页面都引入,或者通过子窗口来变相封装。
</markdown>官方文档不建议这样用。🤣
目前我要展示动画,好像只能这么用,其他的钩子好像行不通,有其他好用的方法可以提供下
可以在onWillDismiss里面拦截掉
什么按钮事件?
就比如弹窗里面有按钮,能否返回按钮的点击事件回调?
在HarmonyOS中封装全局Loading弹窗,并自定义展示动画,你可以通过继承Dialog
类或使用Toast
结合自定义布局来实现。对于全局使用,可以考虑使用服务(Service
)或全局变量控制弹窗的显示与隐藏。自定义动画则需在布局文件中使用<animated-image>
或<animated-vector>
标签,或通过编程方式在Java/Kotlin代码中控制动画播放。确保在合适的位置(如Activity或Fragment的onResume/onPause)管理弹窗的显示与隐藏,以避免内存泄漏。如果问题依旧没法解决请加我微信,我的微信是itying888。