全局Loading弹窗简易版:通过window.createWindow()来实现(HarmonyOS 鸿蒙Next共享包依赖版)
全局Loading弹窗简易版:通过window.createWindow()来实现(HarmonyOS 鸿蒙Next共享包依赖版)
<markdown _ngcontent-uaj-c237="" class="markdownPreContainer">
0.写在前面
测试发现,本文中介绍的实现方式可能导致UI问题,建议采用回调方式实现,请参考:https://developer.huawei.com/consumer/cn/forum/topic/0204151061957140117?fid=0109140870620153026
1.创建共享包(如loadingLib,本示例在项目根目录下创建)
2.在loadingLib共享包中创建加载要显示的Page页面(LoadingPage.ets)
- 为LoadingPage指定路由名称,即:[@Entry](/user/Entry)({ routeName: 'LoadingPage' })
[@Entry](/user/Entry)({ routeName: 'LoadingPage' })
[@Component](/user/Component)
export struct LoadingPage {
[@StorageProp](/user/StorageProp)('loading_message') message: string = '请稍候'
build() {
Stack({ alignContent: Alignment.Center }) {
Column() {
LoadingProgress().width(30).height(30).color(Color.White)
Text(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.message ?? <span class="hljs-string"><span class="hljs-string">'请稍候'</span></span>)
.fontColor(Color.White)
.fontSize(<span class="hljs-number"><span class="hljs-number">16</span></span>)
.margin({ <span class="hljs-attribute"><span class="hljs-attribute">top</span></span>: <span class="hljs-number"><span class="hljs-number">15</span></span> })
.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.textAlign(TextAlign.Center)
}
.justifyContent(FlexAlign.Center)
.width(<span class="hljs-number"><span class="hljs-number">100</span></span>)
.height(<span class="hljs-number"><span class="hljs-number">100</span></span>)
.backgroundColor(<span class="hljs-string"><span class="hljs-string">'#88000000'</span></span>)
.borderRadius(<span class="hljs-number"><span class="hljs-number">8</span></span>)
}
.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.height(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
.backgroundColor(Color.Transparent)
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
3.WindowUtils类用于创建窗口并导出:
- 在loadingLib共享包默认生成的Index.ets中导出WindowUtils类:
export { WindowUtils } from "./src/main/ets/utils/WindowUtils"
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button> - 记得导入LoadingPage.ets:
import 'loadingLib/src/main/ets/pages/LoadingPage'
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button> - WindowUtils.ets
import { display, window } from '@kit.ArkUI'
import { common } from '@kit.AbilityKit'
import 'loadingLib/src/main/ets/pages/LoadingPage'
export class WindowUtils {
/**
- @param message 提示信息
- @param pagePath 自定义loading页面路径,不设置使用上面定义的LoadingPage
*/
static async showLoading(message: ResourceStr = ‘请稍候’, pagePath: string = ‘’) {
let context = getContext()
await window.createWindow({
name: ‘loading_window’,
windowType: window.WindowType.TYPE_DIALOG,
ctx: context
}).then(async win => {
WindowUtils.loadingWindow = win
if (typeof (message) != ‘string’) {
message = context.resourceManager.getStringSync(message) ?? ‘请稍候’
}
AppStorage.setOrCreate(‘loading_message’, message)
if (pagePath == ‘’) {
await win.loadContentByName(“LoadingPage”)
} else {
await win.setUIContent(pagePath)
}
win.setWindowBackgroundColor(’#88000000’)
let d = display.getDefaultDisplaySync()
await win.resize(d.width, d.height)
await win.setWindowFocusable(true)
await win.showWindow()
})
}
static hideLoading() {
// 由于创建窗口后短时间内关闭,后续弹窗很可能无法再次弹出,故设置一个延时
setTimeout(() => {
await window.findWindow(‘loading_window’)?.destroyWindow()
}, 500)
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
4.在需要使用loadingLib共享包的module(如entry)中oh-package.json5添加依赖:
{
"name": "entry",
...
"dependencies": {
...
"loadingLib": "file:../loadingLib"
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
5.在Page或组件中使用:
- 显示Loading:
WindowUtils.showLoading('加载中')
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button> - 隐藏Loading
WindowUtils.hideLoading()
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
2024年年底HarmonyOS 鸿蒙Next免费课程学习地址:https://www.itying.com/goods-1205.html
我也出现了 我把loadingpage类也导出就正常了
对,我后面也这么处理了,我直接在WindowUtils里面import,有个warning,好像不太建议在这边倒是。 但是会引发一个新问题,就是我在onAppear调用hideLoading,会出现没有window,然后一直循环,trycatch之后才不会出现闪退,是不是不能在这边处理啊?
你好 我在测试后发现
在隐藏loading后 调用promptAction 会显示不出现的问题
这个问题我倒没有遇到,暂时还不知道是什么问题
按说影响不了系统的promptAction,是偶尔出现,还是必现?
我这里是必现 而且在hide之后进行push也失效了
请问一下,为LoadingPage指定路由名称 这一步,我会报这个错,得怎么解决呢。
routeName是【api10】才添加的功能,是不是你用的不是api10+版本?
不是,我用的是9,我看现在最新版本不是只到9吗
有HarmonyOS NEXT开发者权限的可以查看api10/11/12的最新文档,如果你没有权限,要么等一等,要么可以查看开源鸿蒙上api10/11文档,v4.0 release对应api10,v4.1 beta对应api11,附链接 https://docs.openharmony.cn/pages/v4.0/zh-cn/application-dev/ui/arkts-layout-development-linear.md
WindowUtils里面把LoadingPage import出去就可以了
import {LoadingPage} from ‘…/components/LoadingPage’ 这样吗
这种情况多数就是LoadingPage这个Page没找到导致的,检查一下LoadingPage的routeName、WindowUtils中loadContentByName(LoadingPage的routeName)是否一致,还有LoadingPage是否在共享包的main_pages.json中配置了
指定路由名称作用是什么,在文档中没找到方便贴一下链接吗
好的感谢,我试了下entry是不能用这种方法跳转自身模块的页面的吗
当前好像是不支持,后续不知会不会添加。
只有window的背景色的原因,我推测是因为传入的是entry的上下文,在没有export LoadingPage的情况下是找不到这个页面的。然后尝试了下是否可以传入entry自身的路由页面作为加载页面,也是可行的,这样或许会更加灵活
可以可以
目的就是为了禁止返回键导致loading消失,如果想返回,可以使用promptAction.openCustomDialog()来实现
请求类里调用显然是不合适的
CustomDialogController 不可以了,app直接打开闪退,
Reason:TypeError
Error name:TypeError
Error message:is not callable
Stacktrace:
Cannot get SourceMap info, dump raw stack:
at ViewPU (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:4925:4925)
at HomeDialogBox (entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/home/components/HomeUniversalComponents.ts:122:9)
at HomePageBottomFunctionView (entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/home/components/HomeComponents.ts:865:22)
at anonymous (entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/home/HomeTab.ts:273:41)
at updateFunc (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:5554:5554)
at observeComponentCreation2 (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:5570:1)
at initialRender (entry/build/default/cache/default/default@CompileArkTS/esmodule/debug/entry/src/main/ets/pages/home/HomeTab.ts:271:13)
at initialRenderView (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:5210:5210)
以上是报错信息,有朋友知道吗?
解决了 ide的bug。 CustomDialog 删除重写一下就好了 。。。。
解决了就好~
在HarmonyOS(鸿蒙)开发中,通过window.createWindow()
来实现全局Loading弹窗是一种较为直接的方法,但需注意该方法的具体实现依赖于鸿蒙系统的API及其版本。以下是一个基于鸿蒙Next共享包依赖版的简要实现思路:
-
确保环境配置:首先,确保你的开发环境已经正确配置鸿蒙Next共享包依赖,并且你的项目能够编译和运行鸿蒙应用。
-
创建Loading窗口:使用
window.createWindow()
方法创建一个新的窗口,该窗口用于显示Loading动画或提示信息。设置窗口的属性,如大小、位置、透明度等,以适应你的需求。 -
管理窗口生命周期:在应用的逻辑中,控制Loading窗口的显示和隐藏。通常,在需要显示Loading状态时调用创建窗口的方法,并在加载完成后关闭窗口。
-
样式与动画:为Loading窗口添加样式和动画效果,以提升用户体验。
-
错误处理:确保在创建和管理窗口时添加适当的错误处理逻辑,以应对可能出现的异常情况。
请注意,window.createWindow()
的具体用法和参数可能随鸿蒙系统的更新而有所变化。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html