全局loading弹窗方法封装-自定义展示loading动画

638 阅读2分钟

在之前预览版本只能通过子窗口的形式来封装全局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,不过用这个方法我们就可以完全自定义弹窗展示了,而不用去封装组件每个页面都引入,或者通过子窗口来变相封装。