【每日学点鸿蒙知识】查看触摸热区范围、直接赋值到剪贴板、组件截图、横竖屏切换、防截图等
1、如何查看触摸热区范围?
前只能通过自定义的方式获取responseRegion。参考文档:触摸热区设置
@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%'}")
// 热区宽度为按钮的一半,点击右侧无响应
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、如何将内容直接复制到剪贴板?
直接把文本上的内容添加进剪切板,不需要跳出选择文本的弹窗,直接复制成功。参考代码如下:
import { pasteboard } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
export struct CopyText {
private textContent: string = '复制我'
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) // 将数据放入剪切板
systemPasteboard.getData().then((data) => {
if (data) {
promptAction.showToast({ message: '复制成功' })
} else {
promptAction.showToast({ message: '复制失败' })
}
})
}
3、组件截图怎么保存将pixelMap存储到系统相册或应用沙箱?
步骤一:确认功能需要使用的能力为组件截图能力:componentSnapshot
截图能力有窗口截图能力 window.snapshot()和 组件截图能力 @ohos.arkui.componentSnapshot。不同的能力范围根据业务选择合适的PAI 解决问题。
步骤二:应用授权以及配置
保存到系统相册需要 申请相册管理模块权限’ohos.permission.WRITE_IMAGEVIDEO’module.json5 配置权限
"requestPermissions": [
{
"name": "ohos.permission.WRITE_IMAGEVIDEO",
"reason": "$string:reason",
"usedScene": {
"abilities": [
"EntryFormAbility"
],
"when": "inuse"
}
},
]
页面入口获取权限
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();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
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) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).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)
}
步骤三:调用组件截图获取 pixelMap
/* 组件截图 */
clickToComponentSnapshot() {
// root 为组件ID
componentSnapshot.get("root", (error: Error, pixmap: image.PixelMap) => {
if (error) {
console.log("error: " + JSON.stringify(error))
return;
}
console.log('截图成功')
this.pixmap = pixmap
})
}
步骤四:保存到系统相册或者应用沙箱
// 保存到系统相册
async savePixmap2SysHelper() {
if (!this.pixmap) {
return
}
const imgBuffer = await this.transferPixelMap2Buffer(this.pixmap)
/* 获取相册管理模块的实例,用于访问和修改相册中的媒体文件。 */
let helper = photoAccessHelper.getPhotoAccessHelper(getContext(this))
/* 指定待创建的文件类型和后缀,创建图片或视频资源,使用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)
/* 关闭文件 */
await fs.close(file.fd)
}
/* 将 pixelMap 转成图片格式 */
transferPixelMap2Buffer(pixelMap: image.PixelMap): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
/**
设置打包参数
format:图片打包格式,只支持 jpg 和 webp
quality:JPEG 编码输出图片质量
bufferSize:图片大小,默认 10M
*/
let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 }
// 创建ImagePacker实例
const imagePackerApi = image.createImagePacker()
imagePackerApi.packing(pixelMap, packOpts).then((buffer: ArrayBuffer) => {
resolve(buffer)
}).catch((err: BusinessError) => {
reject()
})
})
}
/* 保存到应用沙箱 */
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)
/* 关闭文件 */
await fs.close(file.fd)
}
4、如何实现page页面的横竖屏切换?
使用setPreferredOrientation设置横竖屏切换:setPreferredOrientation
import { window } from '@kit.ArkUI';
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
private portrait: boolean = true
changeOrientation = () => {
// 获取当前页面
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) {
// 切换成横屏
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 {
// 切换成竖屏
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('横竖屏切换')
.onClick(() => {
this.changeOrientation()
})
}
.height('100%')
.width('100%')
.backgroundColor(Color.Green)
}}
5、如何实现防截屏功能?
1、设置窗口为隐私模式时,需要entry的module.json5文件中添加相关权限
2、使用setWindowPrivacyMode设置隐私模式
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 {
// 设置窗口为隐私模式,窗口内容将无法被截屏或录屏。
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 已执行`);
} 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%')
}
}