[Daily HarmonyOS Next Knowledge] View Touch Hotspot Range, Direct Clipboard Assignment, Component Screenshot, Portrait/Landscape Switch, Screenshot Prevention, etc.
1. How to view the touch hotspot range?
Currently, the responseRegion
can only be obtained through customization.
Reference document: Touch Hotspot Settings
@Entry
@Component
struct TouchTargetExample {
@State text: string = ''
@State x: number = 0
@State y: number = 0
@State reg_width: string = '50%'
@State reg_height: string = '100%'
build() {
Column({ space: 20 }) {
Text("{x:0,y:0,width:'50%',height:'100%'}")
// The hotspot width is half of the button; clicking the right side has no response.
Button('button')
.responseRegion({ x: this.x, y: this.y, width: this.reg_width, height: this.reg_height })
.onClick(() => {
this.text = 'button clicked'
console.log('button clicked: ' + this.x + ' ' + this.y + ' ' + this.reg_width + ' ' + this.reg_height)
})
Text(this.text).margin({ top: 10 })
}.width('100%').margin({ top: 100 })
}
}
2. How to directly copy content to the clipboard?
Directly add text to the clipboard without popping up a text selection dialog.
Reference code:
import { pasteboard } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
export struct CopyText {
private textContent: string = '复制我' // "Copy Me"
build() {
Column() {
Text(this.textContent)
.fontSize($r('sys.float.ohos_id_text_size_body3'))
.borderRadius(9)
.borderWidth(1)
.padding({ left: 8, right: 8 })
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontWeight(FontWeight.Medium)
.opacity($r('sys.float.ohos_id_alpha_content_secondary'))
.onClick(() => copyText(this.textContent))
}
}
}
function copyText(text: string) {
const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text)
const systemPasteboard = pasteboard.getSystemPasteboard()
systemPasteboard.setData(pasteboardData) // Put data into the clipboard
systemPasteboard.getData().then((data) => {
if (data) {
promptAction.showToast({ message: '复制成功' }) // "Copy successful"
} else {
promptAction.showToast({ message: '复制失败' }) // "Copy failed"
}
})
}
3. How to save component screenshots? Store PixelMap in the system album or app sandbox.
Step 1: Confirm the capability required for component screenshotting: componentSnapshot
Screenshot capabilities include window screenshot (window.snapshot()
) and component screenshot (@ohos.arkui.componentSnapshot
). Choose the appropriate API based on business needs.
Step 2: Application authorization and configuration
To save to the system album, apply for the album management permission in module.json5
:
"requestPermissions": [
{
"name": "ohos.permission.WRITE_IMAGEVIDEO",
"reason": "$string:reason",
"usedScene": {
"abilities": [
"EntryFormAbility"
],
"when": "inuse"
}
},
]
Obtain permissions at the page entry:
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
const permissions: Array<Permissions> = ['ohos.permission.WRITE_IMAGEVIDEO'];
function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
let atManager: abilityAccessCtrl.AtManager =
abilityAccessCtrl.createAtManager();
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// User authorized, proceed with the target operation
} else {
// User denied authorization, prompt for mandatory authorization and guide to settings
return;
}
}
// Authorization successful
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
aboutToAppear(): void {
reqPermissionsFromUser(permissions, this.context)
}
Step 3: Call component screenshot to get PixelMap
/* Component screenshot */
clickToComponentSnapshot() {
// "root" is the component ID
componentSnapshot.get("root", (error: Error, pixmap: image.PixelMap) => {
if (error) {
console.log("error: " + JSON.stringify(error))
return;
}
console.log('截图成功') // "Screenshot successful"
this.pixmap = pixmap
})
}
Step 4: Save to system album or app sandbox
// Save to system album
async savePixmap2SysHelper() {
if (!this.pixmap) {
return
}
const imgBuffer = await this.transferPixelMap2Buffer(this.pixmap)
/* Get the photo access helper instance for album operations */
let helper = photoAccessHelper.getPhotoAccessHelper(getContext(this))
/* Create image/video assets with specified type and suffix, return result via callback */
const uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png')
const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
await fs.write(file.fd, imgBuffer)
/* Close the file */
await fs.close(file.fd)
}
/* Convert PixelMap to image buffer */
transferPixelMap2Buffer(pixelMap: image.PixelMap): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
/* Packing options: format (only jpg/webp), quality, buffer size (default 10M) */
let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 }
const imagePackerApi = image.createImagePacker()
imagePackerApi.packing(pixelMap, packOpts).then((buffer: ArrayBuffer) => {
resolve(buffer)
}).catch((err: BusinessError) => {
reject()
})
})
}
/* Save to app sandbox */
async savePixmal2SystemFileManager() {
if (!this.pixmap) {
return
}
const imgBuffer = await this.transferPixelMap2Buffer(this.pixmap)
const file = fs.openSync(this.filesDir + `/${DateUtil.getTimeStamp()}.png`, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
await fs.write(file.fd, imgBuffer)
/* Close the file */
await fs.close(file.fd)
}
4. How to implement portrait/landscape switching for a page?
Use setPreferredOrientation
to switch between portrait and landscape: setPreferredOrientation
import { window } from '@kit.ArkUI';
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
private portrait: boolean = true
changeOrientation = () => {
// Get the current page context
let context = getContext(this)
window.getLastWindow(context).then((mainWindow) => {
this.changeOrientationInternal(mainWindow)
}).catch((error: ESObject) => {
console.log('getMainWindow error: ' + JSON.stringify(error))
})
}
changeOrientationInternal(lastWindow: window.Window) {
if (this.portrait) {
// Switch to landscape
lastWindow.setPreferredOrientation(window.Orientation.LANDSCAPE).then(() => {
console.log('setPreferredOrientation success')
this.portrait = !this.portrait
}).catch((error: ESObject) => {
console.log('setPreferredOrientation failure' + JSON.stringify(error))
})
} else {
// Switch to portrait
lastWindow.setPreferredOrientation(window.Orientation.PORTRAIT).then(() => {
console.log('setPreferredOrientation success')
this.portrait = !this.portrait
}).catch((error: ESObject) => {
console.log('setPreferredOrientation failure: ' + JSON.stringify(error))
})
}
}
build() {
Column() {
Text(this.message)
.id('Index19HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
Button('横竖屏切换') // "Switch Portrait/Landscape"
.onClick(() => {
this.changeOrientation()
})
}
.height('100%')
.width('100%')
.backgroundColor(Color.Green)
}
}
5. How to implement screenshot prevention?
When setting the window to privacy mode, add relevant permissions in the
module.json5
file of the entry:
Use
setWindowPrivacyMode
to enable privacy mode:
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index20 {
@State message: string = 'Hello World';
window?: window.Window;
aboutToAppear(): void {
window.getLastWindow(getContext(this)).then((mainWindow) => {
this.setWindowPrivacyMode(mainWindow, true)
}).catch((error: ESObject) => {
console.log("getMainWindow error: " + JSON.stringify(error))
})
}
setWindowPrivacyMode(windowClass: window.Window, isPrivacyMode: boolean) {
try {
// Set the window to privacy mode (prevents screenshot/screen recording)
let promise = windowClass.setWindowPrivacyMode(isPrivacyMode);
promise.then(() => {
console.info('Succeeded in setting the window to privacy mode.');
}).catch((err: BusinessError) => {
console.error('Failed to set the window to privacy mode. Cause: ' + JSON.stringify(err));
});
console.info(`setWindowPrivacyMode 已执行`); // "setWindowPrivacyMode executed"
} catch (exception) {
console.error('Failed to set the window to the privacy mode. Cause:' + JSON.stringify(exception));
}
}
build() {
Column() {
Text(this.message)
.id('Index20HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
}
}
Top comments (0)