在之前预览版本只能通过子窗口的形式来封装全局loading弹窗,还要使用到缓存,这就不符合我们的本意了,6月22号升级到beta1之后看了下文档可以通过getUIContext来进行弹窗展示了,下面就展示封装的方法
先引入ComponentContent,window,PromptAction,用于创建弹窗,AnyType是我自定义的ts的any类型,在ets引入ts,ts里声明一个AnyTypt为any
import { AnyType } from '@common/types';
import { ComponentContent, window, PromptAction} from '@kit.ArkUI';
复制
先创建一个loading动画组件,这个是我自定义的loading动画,也可以自行修改组件,定义自己喜欢的loading动画效果,API12多了一个onDidBuild生命周期,可以在组件加载后调用动画。
@Extend(GridItem) function loadingIconItem(){
.width('20lpx')
.height('20lpx')
.borderRadius('10lpx')
}
@Component
struct LoadingAnimation{
@State rotateAngle:number = 0
build() {
Grid(){
GridItem()
.backgroundColor('#6F94B3')
.loadingIconItem()
GridItem()
.backgroundColor('#0F4C81')
.loadingIconItem()
GridItem()
.backgroundColor('#B7C9D9')
.loadingIconItem()
GridItem()
.backgroundColor('#6F94B3')
.loadingIconItem()
}
.rotate({
x:0,
y:0,
z:1,
centerX: '50%',
centerY: '50%',
angle:this.rotateAngle,
})
.width('60lpx')
.height('60lpx')
.columnsTemplate('1fr 1fr')
.rowsTemplate('1fr 1fr')
}
onDidBuild(): void {
animateTo({
duration: 1000,
curve: Curve.Linear,
iterations: -1,
}, () => {
this.rotateAngle = 360
})
}
}
复制
然后再创建一个Builder,用于我们之后使用warpBuilder方法来定义全局Builder
class Params {
text: string = ""
constructor(text: string) {
this.text = text;
}
}
@Builder
function loadingBuilder(params:Params){
Column({space:'26lpx'}){
LoadingAnimation()
Text(params.text)
.fontColor('#666666')
.fontSize('24lpx')
}
.width('200lpx')
}
复制
下面就是主菜了,定义了一个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
}
)
// const component = uiContext.getComponentUtils()
})
}
hide(){
Loading.promptAction.closeCustomDialog(Loading.loadingDialog)
}
}
复制
最后导出
export new Loading()
复制
这个方法不止可以封装全局loading,也可以以一样的方法封装全局弹窗 ,toast等方法,目前官方文档似乎也没有自定义展示图片的toast,不过用这个方法我们就可以完全自定义弹窗展示了,而不用去封装组件每个页面都引入,或者通过子窗口来变相封装。