[Daily HarmonyOS Next Knowledge] Page-level Popup, Return to Desktop API, Cumbersome Portrait-Landscape Switching, Status Bar Color Setting, Screen Always-On Setting
1. Can HarmonyOS uiContext.getPromptAction().openCustomDialog implement a page-level popup?
Can uiContext.getPromptAction().openCustomDialog achieve a page-level popup? Or is there a way to open a page-level popup within a page? The scenario is opening a popup on Page A, where clicking a button in the popup opens a new Page B. When returning from Page B to Page A, the opened popup should still be present.
Currently, no component directly supports this effect. You can simulate the popup by referencing the following demo:
import router from '@ohos.router';
@Entry
@Component
struct Index {
@State textValue: string = 'Hello World'
@State visible: Visibility = Visibility.None
build() {
Stack() {
Row() {
Column() {
Text('Hello World')
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button('click')
.onClick(() => {
console.log("hit me!")
if (this.visible == Visibility.Visible) {
this.visible = Visibility.None
} else {
this.visible = Visibility.Visible
}
})
.backgroundColor(0x777474)
.fontColor(0x000000)
}
.width('100%')
}
.height('100%')
.backgroundColor("#36D")
Column() {
GridRow({
columns:{xs:1 ,sm: 4, md: 8, lg: 12},
breakpoints: { value: ["400vp", "600vp", "800vp"],
reference: BreakpointsReference.WindowSize },
})
{
GridCol({
span:{xs:1 ,sm: 2, md: 4, lg: 8},
offset:{xs:0 ,sm: 1, md: 2, lg: 2}
})
}
}
}
}
}
2. HarmonyOS return to desktop API?
The return-to-desktop API hangs the app in the background.
You can try obtaining the main window object through windowStage and then minimizing the main window with minimize.
Reference document: https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-window
3. Is implementing portrait-landscape switching in HarmonyOS too cumbersome?
The current experience is poor, requiring the rotation function to be written in the onPageShow of each page (Entry).
You can currently customize a utility class to uniformly manage the display mode of all pages. Refer to this demo:
Index7gongju.ets
import Stack from '@ohos.util.Stack';
import { uiObserver, window } from '@kit.ArkUI';
import { common, UIAbility } from '@kit.AbilityKit';
class MyPage {
id?: string
name?: ResourceStr
path?: string
type?: string
lifeCricle?: number
}
interface pageTracking {
page: MyPage
// onshown timestamp
starttime: number
//停留时间
statetime: number
}
// Window identifier (string)
let mypagestack: Record<string, Stack<pageTracking>> = {};
let windows: Record<string, window.Window> = {};
let pageOrientations: Record<string, window.Orientation> = {
"Index": window.Orientation.UNSPECIFIED,
"Logon": window.Orientation.PORTRAIT,
"Detail": window.Orientation.LANDSCAPE,
"Page2": window.Orientation.PORTRAIT_INVERTED,
"Page3": window.Orientation.LANDSCAPE_INVERTED,
}
// Require mainWindow parameters
// The page path of each window must be a chain; default to main window if not passed
export function observerAll(curWindow: window.Window, windowName ?: string) {
// Determine if empty (mainWindow)
if (!windowName || windowName == 'mainWindow') {
windowName = 'mainWindow'
}
let name = windowName as string
windows[name] = curWindow;
let myObserve = curWindow.getUIContext().getUIObserver();
mypagestack[name] = new Stack<pageTracking>();
// Listen for navDestination component lifecycle changes
myObserve.on('navDestinationUpdate', (info) => {
// Map to mypage
let mypage = new MyPage
mypage.id = info.navDestinationId
mypage.name = info.name
mypage.path = info.param?.toString()
mypage.type = 'NavDestination'
mypage.lifeCricle = info.state
//
tracking(mypage, name)
})
// Listen for page lifecycle changes
myObserve.on('routerPageUpdate', (info) => {
// enterPageLoaded = true;
let mypage = new MyPage
mypage.id = String(info.index)
// The name field of router additionally returns the path; take the last name
mypage.name = info.name.split('/').pop()
mypage.path = info.path
mypage.type = 'page'
mypage.lifeCricle = navState(info.state)
tracking(mypage, name)
})
}
// Use mypage for tracking and store lifecycle information
function tracking(mypage: MyPage, windowname: string) {
let stack: Stack<pageTracking> = mypagestack[windowname]
let pagetracking: pageTracking;
// 1. Store page information (abouttoappear) and print all current paths and stack order
// If the stack has one element and it is a navd page, only modify the page type
// Do not push to stack; instead, change the type of the top stack element to navPage
if (mypage.lifeCricle == 2) {
let firstPage = stack.peek()
if (stack.length == 1 && firstPage.page.type == 'NavDestination') {
firstPage = stack.pop()
firstPage.page.type = 'navPage'
stack.push(firstPage)
} else {
stack.push({
page: mypage,
starttime: Date.now(),
statetime: 0,
})
let pagesPath = windowname + ':'
stack.forEach((pagetraking) => {
pagesPath += '->' + pagetraking.page.name?.toString()
})
console.log(pagesPath)
}
}
// 2. Update page information: onshown (refresh start time)
else if (mypage.lifeCricle == 0) {
pagetracking = stack.pop();
pagetracking.starttime = Date.now()
stack.push(pagetracking)
// Change orientation:
let defaultOrientation = window.Orientation.PORTRAIT
if (!!pageOrientations[mypage.name as string]) {
defaultOrientation = pageOrientations[mypage.name as string];
}
windows[windowname].setPreferredOrientation(defaultOrientation)
}
// 3. Update page information: onhidden (accumulate and refresh stay time)
else if (mypage.lifeCricle == 1) {
pagetracking = stack.pop();
pagetracking.statetime = Date.now() - pagetracking.starttime
stack.push(pagetracking)
}
// 4. Output page information (abouttodistoappear) and delete page information
else if (mypage.lifeCricle == 3) {
let pagesPath = windowname + ':'
//
// let time=Date.now()-stack.pop().starttime
// console.log('zyf'+)
// Display current page stay time
// stack.forEach((pagetraking) => {
// // let time=Date.now()-pagetraking.starttime
// // console.log('zyf'+pagetraking.page.name?.toString() + time + 'ms');
// console.log('zyf'+pagetraking.page.name?.toString() + pagetraking.statetime + 'ms');
// })
let popPage = stack.pop()
console.log(popPage.page.name?.toString() + ' statetime ' + popPage.statetime + 'ms')
console.log('popPage :' + popPage.page.name)
stack.forEach((pagetraking) => {
pagesPath += '->' + pagetraking.page.name?.toString()
})
console.log(pagesPath);
}
}
// Unify NavDestination and page lifecycles
function navState(state: number): number {
if (state == 0) {
return 2
} else if (state == 1) {
return 3
} else if (state == 2) {
return 0
} else if (state == 3) {
return 1
} else if (state == 4) {
return 100
} else {
return 4
}
}
Then reference this utility class in Ability and call it in onWindowStageCreate. Refer to the following code:
import { observerAll } from '../pages/Index7gongju';
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Logon', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
try {
let mainWindow = windowStage.getMainWindowSync()
observerAll(mainWindow)
} catch (error) {
console.error(error, " zzzzzz")
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
});
}
4. How to set the status bar to a background image or color in HarmonyOS?
Refer to the following code:
import { BusinessError } from '@ohos.base';
import { window } from '@kit.ArkUI';
@Entry
@Component
struct chuangkou{
build() {
Button("窗口设置").width(100).height(100)
.onClick(()=>{
let SystemBarProperties: window.SystemBarProperties = {
statusBarColor: '#ffee5610',
};
let windowClass: window.Window | undefined = undefined;
try {
let promise = window.getLastWindow(getContext());
promise.then((data) => {
windowClass = data;
windowClass.setWindowSystemBarProperties(SystemBarProperties)
console.info('Succeeded in obtaining the top window. Data: '+ JSON.stringify(data));
}).catch((err: BusinessError) => {
console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err));
});
} catch (exception) {
console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
}
})
}
}
Reference link: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-window-V5#setwindowsystembarproperties9
5. How to set the screen to always on and set the screen brightness to maximum in HarmonyOS?
Refer to the following code to set the screen to always on via a click event, or configure it through other methods based on business needs:
import { BusinessError } from '@ohos.base';
import { window } from '@kit.ArkUI';
import common from '@ohos.app.ability.common';
@Entry
@Component
struct WebPage {
private context = getContext(this) as common.UIAbilityContext;
controller: webView.WebviewController = new webView.WebviewController();
build() {
Column() {
Button('keeplight')
.onClick(() => {
// 1. Get the app's main window.
let windowClass: window.Window | undefined = undefined;
try {
window.getLastWindow(this.context, (err: BusinessError, data) => {
const errCode: number = err.code;
if (errCode) {
console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err));
return;
}
windowClass = data;
console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
try {
windowClass.setWindowKeepScreenOn(true, (err: BusinessError) => {
const errCode: number = err.code;
if (errCode) {
console.error('Failed to set the screen to be always on. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in setting the screen to be always on.');
});
} catch (exception) {
console.error('Failed to set the screen to be always on. Cause: ' + JSON.stringify(exception));
}
});
} catch (exception) {
console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(exception));
}
})
}
}
}
Console output when clicking the button:
05-15 14:48:04.050 12178-12178 A03d00/JSAPP com.examp...lication I Succeeded in obtaining the top window. Data: {}
05-15 14:48:04.059 12178-12178 A03d00/JSAPP com.examp...lication I Succeeded in setting the screen to be always on.
Top comments (0)