import promptAction from '@ohos.promptAction'; import { BusinessError, deviceInfo } from '@kit.BasicServicesKit'; import { HashMap } from '@kit.ArkTS'; import { DeviceInfo } from '../bean/DeviceInfo'; import { common } from '@kit.AbilityKit'; import { md5_hex } from '../util/md5'; export interface Btn { text?: string | Resource; color?: string | Resource; onClick?: () => void } export interface AlertOptions { title?: string msg?: string action?: Btn } export interface ConfirmOptions { title?: string msg?: string confirm?: Btn cancel?: Btn } export interface ListOptions { title?: string cancel?: Btn values: Array onSelected: (index: number, value: T) => void onError?: (msg: string) => void } interface ListItem { content: string } @Builder function customDialogBuilder(option: ListOptions, dialogId: number) { Column() { Text(option.title) .fontSize(13) .textAlign(TextAlign.Center) .width('60%') .maxLines(2) .ellipsisMode(EllipsisMode.END) .textOverflow({ overflow: TextOverflow.Ellipsis }) .visibility(option.title ? Visibility.Visible : Visibility.None) List({ space: 20, initialIndex: 0 }) { ForEach(option.values, (item: T, index: number) => { ListItem() { Text(typeof item === "string" ? item : (item as ListItem).content) .width('100%') .fontSize(16) .textAlign(TextAlign.Center) .onClick(() => { if (ToolsHelper.mapDialog.get(dialogId)) { promptAction.closeCustomDialog(ToolsHelper.mapDialog.get(dialogId)) ToolsHelper.mapDialog.remove(dialogId) } option.onSelected(index, item) }) } }, (item: string) => item) } .listDirection(Axis.Vertical) // 排列方向 .scrollBar(BarState.Off) .friction(0.6) .divider({ strokeWidth: 1, color: 0xEEEEEE, startMargin: 20, endMargin: 20 }) // 每行之间的分界线 .edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring .width('100%') .height(option.values.length < 8 ? `${option.values.length / 16 * 100}%` : '50%') .margin({ top: 20 }) } .padding({ top: 20, bottom: 20, left: 20, right: 20 }) } interface ThrottleInterface { startTime: number; //调用的时间 timeoutNumber: number; //setTimeout的句柄 } /** * 常用方法 */ export class ToolsHelper { /** * 弹出Toast * @param msg */ static log(...args: ESObject[]) { const k = ToolsHelper.getStackKey()?.split('/') console.log(`========>${k ? k[k.length-1].split('.')[0] : ''}::`, args, '\n') } /** * 弹出Toast * @param msg */ static showMessage(msg: string) { console.info(msg); promptAction.showToast({ message: msg, duration: 1500 }); } private static oTime: number = 0 /** * 双击退出 * @param msg */ static doubleAndExit(event?: () => void) { const cTime = new Date().getTime() console.log('=====>', cTime) console.log('=====>', cTime - ToolsHelper.oTime) if (cTime - ToolsHelper.oTime > 800) { ToolsHelper.oTime = cTime ToolsHelper.showMessage('双击退出') } else { if (event) { event() } else { (getContext() as common.UIAbilityContext).terminateSelf() // getContext().getApplicationContext().killAllProcesses(); } } return true } /**kio9 * 弹出Alert弹窗 * @param options */ static showAlertDialog( title?: string, msg?: string, action?: Btn) { try { promptAction.showDialog({ alignment: 1, title: title, message: msg, buttons: [{ text: action?.text ?? "确定", color: action?.color ?? "#000000", }] }) .then(() => { action?.onClick && action?.onClick() }) .catch((err: Error) => { ToolsHelper.showMessage(err.message) }) } catch (error) { let message = (error as BusinessError).message ToolsHelper.showMessage(message) } } /** * 弹出Confirm弹窗 * @param options */ static showConfirmDialog(options: ConfirmOptions) { try { promptAction.showDialog({ alignment: 1, title: options.title, message: options.msg, buttons: [{ text: options.confirm?.text ?? "确定", color: options.confirm?.color ?? "#000000", }, { text: options.cancel?.text ?? "取消", color: options.cancel?.color ?? "#666666", }] }) .then((data) => { if (data.index === 0) { options.confirm?.onClick && options.confirm.onClick() } else { options.cancel?.onClick && options.cancel.onClick() } }) .catch((err: Error) => { ToolsHelper.showMessage(err.message) }) } catch (error) { let message = (error as BusinessError).message ToolsHelper.showMessage(message) } } public static mapDialog = new HashMap() /** * 弹出List弹窗 * @param options values 如果是非string列表的话,需要存在content字段 */ static showListDialog(options: ListOptions, p: object) { let isSuccess: Array = [] options.values.forEach((item, index) => { if (typeof item !== 'string') { if (!(item as ListItem).content) { isSuccess.push(index) } } }) if (isSuccess.length > 0) { options.onError && options.onError(`第(${isSuccess.join("、")})个数据中,没有content字段。`) } else { const dialogTag = new Date().getTime() promptAction.openCustomDialog({ alignment: 1, builder: customDialogBuilder.bind(p, options, dialogTag) }).then((dialogId: number) => { ToolsHelper.mapDialog.set(dialogTag, dialogId) }) } } /** * 弹出自定义弹窗 * @param alignment 弹窗在竖直方向上的对齐方式 */ static showCustomDialog(b: CustomBuilder, alignment?: DialogAlignment) { const dialogTag = new Date().getTime() promptAction.openCustomDialog({ alignment: alignment ?? DialogAlignment.Center, builder: b }).then((dialogId: number) => { ToolsHelper.mapDialog.set(dialogTag, dialogId) }).catch((error: Error) => { console.log('>>>>>', JSON.stringify(error)) }) } /** * 获取调用栈第一个类 */ static getStackKey() { let stack = new Error().stack if (stack) { let list = JSON.stringify(stack).split('\\n') let a = list[list.length-2].split(':')[0].split('(')[1] return a } return undefined } private static deviceInfo: DeviceInfo /** * 获取设备信息 * @returns {@link DeviceInfo} */ static getDeviceInfo() { if (!ToolsHelper.deviceInfo) { ToolsHelper.deviceInfo = new DeviceInfo() ToolsHelper.deviceInfo.ODID = deviceInfo.ODID ToolsHelper.deviceInfo.manufacture = deviceInfo.manufacture ToolsHelper.deviceInfo.brand = deviceInfo.brand ToolsHelper.deviceInfo.osFullName = deviceInfo.osFullName } return ToolsHelper.deviceInfo } /** * 防抖动函数,调用后会延迟wait时间执行,当在wait时间内再次对同一函数调用,则会取消之前的定时器,重新定时 * @param fun * @param wait */ static debounceHold(fun: Function, wait: number = 1500) { let funcValue1 = ToolsHelper.getUniqueId(fun) let hash = md5_hex(funcValue1) if (ToolsHelper.setTimeOutMap.get(hash)) { clearTimeout(ToolsHelper.setTimeOutMap.get(hash)?.timeoutNumber) ToolsHelper.setTimeOutMap.delete(hash) } // ToolsHelper.checkTimeOutNumber() let timeoutNumber = setTimeout(() => { ToolsHelper.setTimeOutMap.get(hash) && clearTimeout(ToolsHelper.setTimeOutMap.get(hash)?.timeoutNumber) ToolsHelper.setTimeOutMap.delete(hash) // 执行函数调用 fun() }, wait) ToolsHelper.setTimeOutMap.set(hash, { timeoutNumber: timeoutNumber, startTime: new Date().getTime(), }) } private static setTimeOutMap: Map = new Map() private static uniqueIdMap = new WeakMap(); private static getUuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { let r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); } private static getUniqueId(fun: Function): string { if (!ToolsHelper.uniqueIdMap.has(fun)) { ToolsHelper.uniqueIdMap.set(fun, ToolsHelper.getUuid()); } return ToolsHelper.uniqueIdMap.get(fun)!; } }