Floating Window Implementation for Call Effect in HarmonyOS Next
In mobile application development, floating windows are a common feature. For example, during WeChat audio/video calls, to ensure users can view and handle other functions while on a call, the call page can be displayed as a floating window. This article discusses how to implement such a floating window function for call effects in HarmonyOS Next.
The window system is the core capability supporting floating windows. Let's first introduce the window module of HarmonyOS Next.
Window Module
Fundamental Role of the Window Module
The window module plays a core role in HarmonyOS Next. For application developers, it provides a complete framework for interface display and interaction, facilitating the construction of creative applications. End users can use it to control application interfaces freely, focusing on single tasks or flexibly switching and coordinating multiple tasks. From an operating system perspective, the window module acts as a smart "dispatcher," orderly organizing different application interfaces to ensure smooth and stable system operation.
Diverse Uses of the Window Module
- Provider of Window Objects: The window module of HarmonyOS Next is the foundation for application and system interface presentation. Developers use it to load colorful UI interfaces, perfectly integrating application functions and visuals to let users intuitively experience the application's charm.
- Organizer of Display Relationships: The system has various window types. System windows such as volume bars, notification bars, etc., ensure system functions are accessible; application windows include main windows and sub-windows. The application main window is the "main stage" of the application, clearly visible in the task management interface; application sub-windows, like pop-ups and floating windows, assist the main window. The window module accurately maintains their stacking hierarchy and position attributes, and users can adjust them as needed to create a personalized desktop layout.
- Giver of Window Decoration and Animation Effects: The default window title bar and border integrate practical operation buttons and convenient drag-and-resize functions, simplifying user operations. Window animations enhance interaction, with smooth animations during window display, hiding, and switching, presented automatically by the system without developer intervention.
- Precise Dispatcher of Input Events: Touch and mouse events are delivered precisely by position and size based on window status and focus, while keyboard events go directly to the focused window. Developers can also customize a window's touch and focus attributes through interfaces to meet diverse interaction needs.
Flexible Switching of Application Window Modes
HarmonyOS Next supports three application window modes—full-screen, split-screen, and free window—demonstrating powerful multi-window capabilities. The full-screen mode allows an application to occupy the entire view for an immersive experience; the split-screen mode lets two applications run side by side with a draggable dividing line for resource comparison and collaborative processing; the free window mode gives users ultimate freedom to adjust size and position, keeping multiple windows organized on the screen with quick focus on click, boosting multi-tasking efficiency.
Introduction to Window APIs
Windows provide basic capabilities for window management, including creating, destroying, setting attributes, and scheduling between windows. The window module offers the following common window-related functions:
-
Window
: The current window instance, the basic unit managed by the window manager. -
WindowStage
: The window manager, managing each basic window unit. The following is a list of methods extracted from the link:
WindowStage Methods
-
getMainWindow(callback: AsyncCallback<Window>): void
: Get the main window under this WindowStage instance using an asynchronous callback. -
getMainWindow(): Promise<Window>
: Get the main window under this WindowStage instance using a Promise-based asynchronous callback. -
getMainWindowSync(): Window
: Get the main window under this WindowStage instance synchronously. -
createSubWindow(name: string, callback: AsyncCallback<Window>): void
: Create a subwindow under this WindowStage instance using an asynchronous callback. -
createSubWindow(name: string): Promise<Window>
: Create a subwindow under this WindowStage instance using a Promise-based asynchronous callback. -
createSubWindowWithOptions(name: string, options: SubWindowOptions): Promise<Window>
: Create a subwindow under this WindowStage instance with set parameters using a Promise-based asynchronous callback. -
getSubWindow(callback: AsyncCallback<Array<Window>>): void
: Get all subwindows under this WindowStage instance using an asynchronous callback. -
getSubWindow(): Promise<Array<Window>>
: Get all subwindows under this WindowStage instance using a Promise-based asynchronous callback. -
loadContent(path: string, storage: LocalStorage, callback: AsyncCallback<void>): void
: Load specific page content for the main window of the current WindowStage, passing state attributes via LocalStorage with an asynchronous callback. -
loadContent(path: string, storage?: LocalStorage): Promise<void>
: Load specific page content for the main window of the current WindowStage, passing state attributes via LocalStorage with a Promise-based asynchronous callback. -
loadContent(path: string, callback: AsyncCallback<void>): void
: Load specific page content for the main window of the current WindowStage using an asynchronous callback. -
loadContentByName(name: string, storage: LocalStorage, callback: AsyncCallback<void>): void
: Load a named route page for the current WindowStage, passing state attributes via LocalStorage with an asynchronous callback. -
loadContentByName(name: string, callback: AsyncCallback<void>): void
: Load a named route page for the current WindowStage using an asynchronous callback. -
loadContentByName(name: string, storage?: LocalStorage): Promise<void>
: Load a named route page for the current WindowStage, passing state attributes via LocalStorage with a Promise-based asynchronous callback. -
on(eventType: 'windowStageEvent', callback: Callback<WindowStageEventType>): void
: Enable listening for WindowStage lifecycle changes. -
off(eventType: 'windowStageEvent', callback?: Callback<WindowStageEventType>): void
: Disable listening for WindowStage lifecycle changes. -
setDefaultDensityEnabled(enabled: boolean): void
: Set whether the application uses the system's default density.
Window Methods
-
showWindow(callback: AsyncCallback<void>): void
: Show the current window using an asynchronous callback, supporting system windows, application subwindows, or elevating the hierarchy of a displayed application main window to the top. -
showWindow(): Promise<void>
: Show the current window using a Promise-based asynchronous callback. -
destroyWindow(callback: AsyncCallback<void>): void
: Destroy the current window using an asynchronous callback. -
destroyWindow(): Promise<void>
: Destroy the current window using a Promise-based asynchronous callback. -
moveWindowTo(x: number, y: number, callback: AsyncCallback<void>): void
: Move the window position using an asynchronous callback. -
moveWindowTo(x: number, y: number): Promise<void>
: Move the window position using a Promise-based asynchronous callback. -
resize(width: number, height: number, callback: AsyncCallback<void>): void
: Change the current window size using an asynchronous callback. -
resize(width: number, height: number): Promise<void>
: Change the current window size using a Promise-based asynchronous callback. -
getWindowProperties(): WindowProperties
: Get the properties of the current window. -
getWindowAvoidArea(type: AvoidAreaType): AvoidArea
: Get the area that the current window content should avoid. -
setWindowFocusable(isFocusable: boolean, callback: AsyncCallback<void>): void
: Set whether the window is touchable using an asynchronous callback. -
setWindowFocusable(isFocusable: boolean): Promise<void>
: Set whether the window is touchable using a Promise-based asynchronous callback. -
setWindowBackgroundColor(color: string): void
: Set the window background color. -
setWindowBrightness(brightness: number, callback: AsyncCallback<void>): void
: Allow the application main window to set the screen brightness using an asynchronous callback. -
setWindowBrightness(brightness: number): Promise<void>
: Allow the application main window to set the screen brightness using a Promise-based asynchronous callback. -
setWindowSystemBarProperties(systemBarProperties: SystemBarProperties, callback: AsyncCallback<void>): void
: Set the properties of the main window's three-key navigation bar and status bar using an asynchronous callback. -
setWindowSystemBarProperties(systemBarProperties: SystemBarProperties): Promise<void>
: Set the properties of the main window's three-key navigation bar and status bar using a Promise-based asynchronous callback. -
setWindowLayoutFullScreen(isLayoutFullScreen: boolean, callback: AsyncCallback<void>): void
: Set whether the main or subwindow layout is immersive using an asynchronous callback. -
setWindowLayoutFullScreen(isLayoutFullScreen: boolean): Promise<void>
: Set whether the main or subwindow layout is immersive using a Promise-based asynchronous callback. -
isWindowShowing(): boolean
: Check if the current window is displayed. -
on(type: 'windowSizeChange', callback: Callback<Size>): void
: Enable listening for window size changes. -
off(type: 'windowSizeChange', callback?: Callback<Size>): void
: Disable listening for window size changes. -
on(type: 'avoidAreaChange', callback: Callback<AvoidAreaOptions>): void
: Enable listening for changes in the current application window's system avoidance area. -
off(type: 'avoidAreaChange', callback?: Callback<AvoidAreaOptions>): void
: Disable listening for changes in the current application window's system avoidance area. -
on(type: 'keyboardHeightChange', callback: Callback<number>): void
: Enable listening for changes in the fixed soft keyboard height. -
off(type: 'keyboardHeightChange', callback?: Callback<number>): void
: Disable listening for changes in the fixed soft keyboard height. -
on(type: 'touchOutside', callback: Callback<void>): void
: Enable listening for click events outside the current window area. -
off(type: 'touchOutside', callback?: Callback<void>): void
: Disable listening for click events outside the current window area. -
on(type: 'screenshot', callback: Callback<void>): void
: Enable listening for screenshot events. -
off(type: 'screenshot', callback?: Callback<void>): void
: Disable listening for screenshot events. -
on(type: 'windowEvent', callback: Callback<WindowEventType>): void
: Enable listening for window lifecycle changes. -
off(type: 'windowEvent', callback?: Callback<WindowEventType>): void
: Disable listening for window lifecycle changes. -
on(type: 'windowVisibilityChange', callback: Callback<boolean>): void
: Enable listening for changes in the current window's visibility status. -
off(type: 'windowVisibilityChange', callback?: Callback<boolean>): void
: Disable listening for changes in the current window's visibility status. -
on(type: 'noInteractionDetected', timeout: number, callback: Callback<void>): void
: Enable listening for no interaction events within a specified timeout for the current window. -
off(type: 'noInteractionDetected', callback?: Callback<void>): void
: Disable listening for no interaction events within a specified timeout for the current window. -
on(type: 'windowStatusChange', callback: Callback<WindowStatusType>): void
: Enable listening for window mode changes. -
off(type: 'windowStatusChange', callback?: Callback<WindowStatusType>): void
: Disable listening for window mode changes. -
on(type: 'windowRectChange', callback: Callback<RectChangeOptions>): void
: Enable listening for window rectangle changes. -
off(type: 'windowRectChange', callback?: Callback<RectChangeOptions>): void
: Disable listening for window rectangle changes. -
on(type: 'subWindowClose', callback: Callback<void>): void
: Trigger this event when a subwindow closes. -
off(type: 'subWindowClose', callback?: Callback<void>): void
: Disable listening for subwindow close events. -
minimize(callback: AsyncCallback<void>): void
: Minimize the window using an asynchronous callback. -
minimize(): Promise<void>
: Minimize the window using a Promise-based asynchronous callback. -
maximize(presentation?: MaximizePresentation): Promise<void>
: Called by the main window to maximize, using a Promise-based asynchronous callback. -
recover(): Promise<void>
: Restore the main window from full-screen, maximized, or split-screen mode to a floating window, resuming its size and position before entering the mode. -
getWindowLimits(): WindowLimits
: Get the size limits of the current application window. -
setWindowLimits(windowLimits: WindowLimits): Promise<WindowLimits>
: Set the size limits of the current application window. -
setWindowMask(windowMask: Array<Array<number>>): Promise<void>
: Set the mask for an irregular window. -
keepKeyboardOnFocus(keepKeyboardFlag: boolean): void
: Retain the soft keyboard created by other windows when the window gains focus. -
setWindowDecorVisible(isVisible: boolean): void
: Set whether the window title bar is visible. -
setSubWindowModal(isModal: boolean): Promise<void>
: Set whether the subwindow's modal attribute is enabled. -
setWindowDecorHeight(height: number): void
: Set the height of the window title bar. -
getTitleButtonRect(): TitleButtonRect
: Get the rectangular area of the minimize, maximize, and close buttons on the title bar of the main window or a decorated subwindow. -
getWindowStatus(): WindowStatusType
: Get the mode of the current application window. -
isFocused(): boolean
: Check if the current window has focus. -
createSubWindowWithOptions(name: string, options: SubWindowOptions): Promise<Window>
: Create a subwindow under the main window or subwindow. -
enableLandscapeMultiWindow(): Promise<void>
: Enable landscape multi-window support when entering an interface that supports landscape layout. -
disableLandscapeMultiWindow(): Promise<void>
: Disable landscape multi-window support when exiting an interface that supports landscape layout. -
setDialogBackGestureEnabled(enabled: boolean): Promise<void>
: Set whether a modal window responds to gesture back events.
Implementation Methods for Floating Window Capabilities in HarmonyOS Next
Before introducing floating window implementation, let's understand the window types provided by HarmonyOS Next.
Window Types
The window module of HarmonyOS divides window interfaces into two basic types: system windows and application windows.
- System Windows: These refer to windows that complete specific system functions, such as volume bars, wallpapers, notification bars, status bars, and navigation bars.
-
Application Windows: Different from system windows, these refer to windows related to application display. Depending on the displayed content, application windows are further divided into application main windows and application subwindows.
- Application Main Window: Displays the application interface and appears in the "task management interface."
- Application Subwindow: Displays application pop-ups.
System restrictions on application windows are as follows:
- Application main and subwindows have size limits: width range
[320, 2560]
vp, height range[240, 2560]
vp. - System windows have size limits: width range
(0, 2560]
vp, height range(0, 2560]
vp.
Management of application windows is mainly reflected in:
- Window Immersive Capability: Controls system windows like status bars and navigation bars to reduce their abruptness, providing the best user experience. This capability only takes effect when the application main window is in full-screen mode. Typically, application subwindows (auxiliary windows like pop-ups and floating windows) and application main windows in free window mode cannot use immersive capabilities.
- Floating Window: A global floating window is a special application window that can remain visible in the foreground even when the application main window and corresponding Ability go to the background. It can be used for continuing video playback in a small window after the application goes to the background or creating quick entrances like floating balls for specific applications. Applications need to apply for corresponding permissions before creating floating windows.
Smart Multi-Window
Smart multi-window is a multi-tasking solution allowing users to run multiple application windows simultaneously in floating or split-screen mode on the same screen. In smart multi-window display mode, users can arrange application window positions and sizes as needed, mainly in two forms:
Floating Window: A non-full-screen application window floating on the device screen, typically used for temporarily handling another task or short-term multi-tasking while a full-screen task is running, such as replying to messages while browsing the web.
Split-Screen: Usually used for long-term parallel use of two applications, such as viewing shopping guides while browsing products, watching videos while playing games, or taking notes while watching educational videos.
Smart multi-window is a system capability that can be set and adapted for the entire APP, not suitable for our page-level floating window scenario.
Picture-in-Picture (PiP)
In scenarios like video playback, video conferences, and video calls, applications can use PiP capability to present video content in a small window (PiP mode). After switching to PiP mode, users can perform other interface operations to enhance the experience. Common use cases for PiP include:
- Video playback
- Video calls
- Video conferences
- Live broadcasts
Effect display:
PiP windows provide the following interaction methods:
- Single-click: If the PiP control layer is not displayed, show it; if displayed, hide it (auto-hide after 3 seconds).
- Double-click: Enlarge or reduce the PiP window.
- Drag: Move the PiP window anywhere on the screen. Dragging to the left/right edge hides the window, which can be restored by clicking the hidden icon on the edge.
PiP restrictions:
- Requires a system supporting the SystemCapability.Window.SessionManager capability (refer to the system capability usage guide).
- For security, applications cannot start PiP via
startPiP
when in the background. For scenarios requiring starting PiP when the application returns to the background, usesetAutoStartEnabled(true)
for automatic start. Additionally, PiP is suitable for video scenes. Voice call scenes without video are unsuitable, and PiP has minimum width/height requirements that may not meet our needs.
Floating Window
Based on window capabilities, a floating window can be created as a foreground window on top of existing tasks. Even if the task creating the floating window goes to the background, the floating window remains in the foreground, usually above all application windows. Developers can
Top comments (0)