//悬浮窗工具类
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
import { Logger } from '@mbbase/common-ui';
import * as FloatedWindowPage from './FloatedWindowPage'; // 导入命名路由页面
const TAG = '[FloatedWindowUtils]';
export interface FloatedWindowParams {
width: number;
height: number;
x: number;
y: number;
backgroundColor?: string;
}
export class FloatedWindowUtils {
public static showSubWindow(windowStage: window.WindowStage | undefined,
subWindowParams: FloatedWindowParams) {
if (!windowStage) {
Logger.error(TAG, `windowStage is undefined.`);
return;
}
windowStage.createSubWindow(FloatedWindowPage.subWindowName, (err, subWindow) => {
try {
subWindow.loadContentByName(FloatedWindowPage.entryName, (err: BusinessError) => {
if (err.code) {
Logger.error(TAG, `Failed to load the content. Cause: ${err.message}.`);
return;
}
Logger.info('Succeeded in loading the content.');
subWindow.setWindowBackgroundColor(subWindowParams.backgroundColor ?? '#00ffffff');
subWindow.moveWindowTo(subWindowParams.x, subWindowParams.y);
subWindow.resize(subWindowParams.width, subWindowParams.height)
subWindow.setWindowTouchable(true);
subWindow.showWindow();
// subWindow.setWindowBackgroundColor(Color.Transparent.toString());
subWindow.setWindowLayoutFullScreen(true);
})
} catch (err) {
Logger.error('failed to create subWindow Cause:' + err);
}
})
}
public static async getFloatedWindow(): Promise<window.Window | undefined> {
let windowStage = await AppStorage.get<window.WindowStage>('windowStage');
if (!windowStage) {
return undefined;
}
let subList = await windowStage.getSubWindow()
for (let i = 0; i < subList.length; i++) {
let aa: window.WindowProperties = subList[i].getWindowProperties()
// if (aa.name == 'FloatedWindow') {
return subList[i];
// }
}
return undefined;
}
public static async destroySubWindow() {
try {
let subWindow: window.Window = await window.findWindow(FloatedWindowPage.subWindowName)
if (!subWindow) {
Logger.info('subWindow is undefined.');
return;
}
subWindow.destroyWindow((err: BusinessError) => {
if (err.code) {
Logger.error(TAG, `Failed to destroy the window. Cause: ${err.message}.`);
return;
}
AppStorage.set<window.Window>('subWindow', undefined);
Logger.info('Succeeded in destroying the window.');
});
} catch (err) {
Logger.error('Find subWindow failed. Cause:' + err);
}
}
public static async moveSubWindow(x: number, y: number) {
try {
let subWindow: window.Window = window.findWindow(FloatedWindowPage.subWindowName)
if (!subWindow) {
Logger.info('subWindow is undefined.');
return;
}
subWindow.moveWindowTo(x, y, (err: BusinessError) => {
if (err.code) {
Logger.error(TAG, `Failed to move the window. Cause: ${err.message}.`);
return;
}
Logger.info('Succeeded in moving the window.', x, y);
});
} catch (err) {
Logger.error('Find subWindow failed. Cause:' + err);
}
}
public static async resizeSubWindow(width: number, height: number) {
try {
let subWindow: window.Window = window.findWindow(FloatedWindowPage.subWindowName)
if (!subWindow) {
Logger.info('subWindow is undefined.');
return;
}
subWindow.resize(vp2px(width), vp2px(height), (err: BusinessError) => {
if (err.code) {
Logger.error(TAG, `Failed to change the window size. Cause: ${err.message}.`);
return;
}
Logger.info('Succeeded in changing the window size.');
})
} catch (err) {
Logger.error('Find subWindow failed. Cause:' + err);
}
}
}
//悬浮窗页面
import { display, window } from '@kit.ArkUI'
import { MBRouter } from '@mbbase/router'
export const entryName: string = 'FloatedWindowName';
export const subWindowName: string = 'FloatedWindow';
@Entry({ routeName: entryName })
@Component
export struct FloatedWindowPage {
@State subWindow: window.Window = window.findWindow(subWindowName)
@State @Watch('moveWindow') windowPosition: WindowPosition = {
x: 40,
y: 800
}
moveWindow() {
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
}
build() {
Row() {
Text('悬浮窗')
.fontColor(Color.Red)
.fontWeight(800)
.onClick(() => {
// MBRouter.push({ url: "ymm://test/debug" })
})
}.width('100%').height('100%')
.gesture(
PanGesture()
.onActionStart(() => {
})
.onActionUpdate((event: GestureEvent) => {
this.windowPosition.x += event.offsetX;
this.windowPosition.y += event.offsetY;
let top = 80;
let bottom =
display.getDefaultDisplaySync().height - this.subWindow.getWindowProperties().windowRect.height
- top;
if (this.windowPosition.y < top) {
this.windowPosition.y = top;
} else if (this.windowPosition.y > bottom) {
this.windowPosition.y = bottom;
}
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
})
.onActionEnd((event: GestureEvent) => {
let rect = this.subWindow.getWindowProperties().windowRect;
if (this.windowPosition.x + rect.width / 2 >= display.getDefaultDisplaySync().width / 2) {
this.windowPosition.x = display.getDefaultDisplaySync().width - rect.width;
} else if (event.offsetX < display.getDefaultDisplaySync().width / 2) {
this.windowPosition.x = 0;
}
let top = 80;
let bottom =
display.getDefaultDisplaySync().height - rect.height
- top;
if (this.windowPosition.y < top) {
this.windowPosition.y = top;
} else if (this.windowPosition.y > bottom) {
this.windowPosition.y = bottom;
}
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
})
)
}
}
export interface WindowPosition {
x: number,
y: number
}