1、HarmonyOS instanceof判断错误?
ArkTS部分支持instanceof,可参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/typescript-to-arkts-migration-guide-V5
instanceof运算符在传递的过程中可能会发生以下情况:对象的属性在传递的过程中被修改。对象的引用在传递的过程中被改变。对象的构造函数可能尚未完成执行,导致对象状态不完整。以上情况都可能导致在接收线程中使用instanceof进行类型判断时出现错误。因此,直接依赖instanceof进行类型判断不够安全。
2、HarmonyOS 下刘海的高宽获取不到?
通过 window.getWindowAvoidArea(window.AvoidAreaType.TYPE_CUTOUT) 获取刘海的高宽的时候,没有取到下刘海的数据。
获取导航栏高度,设置window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
3、HarmonyOS 有没有隐私政策弹框的demo?
可以使用Stack组件模拟实现Dialog的效果,页面跳转之后返回 可以做到 Dialog依然显示的效果
import router from '@ohos.router';
@Entry
@Component
struct First {
@State textValue: string = 'Hello World'
// 显隐控制设置为不占用
@State visible: Visibility = Visibility.None
@State path: string = "pages/Index"
build() {
// 使用stack可以实现假的dialog覆盖原页面上面
Stack() {
Row() {
// 初始页面
Column() {
Text('Hello World')
.fontSize(50)
.fontWeight(FontWeight.Bold)
// 触发dialog的地方
Button('click')
.onClick(() => {
//用于检测点击事件是否透传到原来的页面,我测了一下是没有透传的,符合dialog规范
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(0x885555)
//这里开始是构造弹窗效果主要需要修改的地方,首先是加了一个半透明灰色的蒙层效果
Text('')
.onClick(() => {
if (this.visible == Visibility.Visible) {
this.visible = Visibility.None
} else {
this.visible = Visibility.Visible
}
})
.width('100%')
.height('100%')// 透明度可以自己调节一下
.opacity(0.16)
.backgroundColor(0x000000)
.visibility(this.visible)
Column() {
// 这个可以调节对话框效果,栅格布局,xs,sm,md,lg分别为四种规格
// 下面的breakpoints是用来区别当前属于哪个类型的断点
// gridRow里的栅格数量为总数,gridCol里的就是偏移和假Dialog所占据的栅格数
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
}
}) {
// 这里放的就是原Dialog里的column里的东西,稍微改改应该就可以用了
Column() {
Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 })
TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
.onChange((value: string) => {
this.textValue = value
})
Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 })
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('cancel')
.onClick(() => {
if (this.visible == Visibility.Visible) {
this.visible = Visibility.None
} else {
this.visible = Visibility.Visible
}
}).backgroundColor(0xffffff).fontColor(Color.Black)
Button('jump')
.onClick(() => {
router.pushUrl({
//url: 'pages/Index'
url: this.path
})
}).backgroundColor(0xffffff).fontColor(Color.Red)
}.margin({ bottom: 10 })
}
.backgroundColor(0xffffff)
.visibility(this.visible)
.clip(true)
.borderRadius(20)
}
}
}.width('95%') //设置弹窗宽度
}
}
}
4、HarmonyOS 滑动下一页效果应该如何做?
参考代码:
@Entry
@Component
struct NovelPage {
@Provide('fontSize') @Watch('onFontSizeChange') fontSize: number = Constants.INIT_FONT_SIZE;
@Provide('bgColorIndex') @Watch('onBgColorChanged') bgColorIndex: BGColorType = BGColorType.WHITE;
@Provide('bgColor') bgColor: string = BG_COLOR_ARRAY[BGColorType.WHITE];
@Provide('offsetX') offsetX: number = 0
@Provide('offsetY') offsetY: number = 0;
@Provide('screenH') screenH: number = 0;
@Provide('screenW') screenW: number = 0;
@Provide('sumRow') sumRow: number = 0;
@Provide('rowWord') rowWord: number = 0;
@Provide('rotateAngleOne') rotateAngleOne: number = Constants.INIT_ROTATE_ANGLE_ONE;
@Provide('rotateAngleTwo') rotateAngleTwo: number = 0.0;
@Provide('curPosition') curPosition: number = 0;
@Provide('turnStyle') turnStyle: FlipPageType = FlipPageType.SLIDE_FLIP_PAGE;
@Provide('currentPageNum') @Watch('onFlush') currentPageNum: number = 1;
@Provide('pageWordSum') pageWordSum: number = 0;
@Provide('light') light: number = Constants.INIT_SCREEN_LIGHT;
@Provide('isSystemLight') isSystemLight: boolean = false;
@Provide('rowGap') rowGap: number = Constants.INIT_ROW_GAP;
@State currentStartIndex: number = 0;
@State isShow: boolean = false;
@State isFontChanged: boolean = false;
aboutToAppear(): void {
this.screenW = px2vp(display.getDefaultDisplaySync().width);
this.screenH = px2vp(display.getDefaultDisplaySync().height - (AppStorage.get('avoidHeight') as number));
this.sumRow = Math.floor((this.screenH) / (this.fontSize + this.rowGap));
this.rowWord = Math.floor((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) / this.fontSize);
this.simulatePageContent();
this.changeSystemBarStatue();
}
onFontSizeChange() {
this.sumRow = Math.floor((this.screenH) / (this.fontSize + this.rowGap));
this.rowWord = Math.floor((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) / this.fontSize);
let pageWordSum = this.sumRow * this.rowWord;
if (this.currentStartIndex > pageWordSum) {
this.currentPageNum = Math.floor(this.currentStartIndex / (pageWordSum)) +
(this.currentStartIndex > 1 && this.currentStartIndex % pageWordSum > 0 ? 2 : 1);
} else if (this.currentStartIndex > 0) {
this.currentPageNum = 2;
} else {
Logger.info('currentStartIndex = ' + this.currentStartIndex);
}
this.isFontChanged = true;
this.simulatePageContent();
}
changeSystemBarStatue(): void {
window.getLastWindow(getContext(this), (err, data) => {
const errCode = err.code;
if (errCode) {
return;
}
let SystemBarProperties: window.SystemBarProperties = {
statusBarColor: BG_COLOR_ARRAY[this.bgColorIndex],
navigationBarColor: BG_COLOR_ARRAY[this.bgColorIndex],
navigationBarContentColor: Constants.TRANSPARENT
};
try {
data.setWindowSystemBarProperties(SystemBarProperties, (err: BusinessError) => {
const errCode: number = err.code;
if (errCode) {
Logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err));
return;
}
data.setWindowBackgroundColor(BG_COLOR_ARRAY[this.bgColorIndex]);
});
} catch (exception) {
Logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(exception));
}
});
}
onBgColorChanged() {
this.changeSystemBarStatue();
}
onFlush() {
Logger.info('currentPageNum=' + this.currentPageNum + ', isFontChanged=' + this.isFontChanged);
if (this.isFontChanged && this.currentPageNum === 1) {
this.isFontChanged = false;
this.currentStartIndex = 0;
}
}
simulatePageContent() {
this.offsetY = 0;
this.rotateAngleTwo = 0.0;
this.rotateAngleOne = Constants.INIT_ROTATE_ANGLE_ONE;
}
private clickAnimateTo(isLeft: Boolean) {
if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) {
animateTo({
duration: Constants.SLIDE_DURATION,
curve: Curve.EaseOut,
onFinish: () => {
if (this.offsetX > 0) {
this.currentPageNum > 0 ? this.currentPageNum - 1 : this.currentPageNum;
this.currentStartIndex -= this.sumRow * this.rowWord;
}
if (this.offsetX < 0) {
this.currentPageNum += 1;
this.currentStartIndex += this.sumRow * this.rowWord;
}
Logger.info(this.currentStartIndex.toString());
this.offsetX = 0;
this.simulatePageContent();
}
}, () => {
if (isLeft) {
this.offsetX = this.screenW;
} else {
this.offsetX = -this.screenW;
}
})
}
}
build() {
Row() {
if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) {
SlideFlipView({
currentStartIndex: this.currentStartIndex
})
}
}
.width(Constants.FULL_PERCENT)
.height(Constants.FULL_PERCENT)
.bindSheet(
$$this.isShow,
this.myBuilder(),
{
height: SheetSize.FIT_CONTENT,
detents: [Constants.SHEET_HEIGHT, Constants.SHEET_HEIGHT + 1],
showClose: true,
dragBar: true,
title: { title: Constants.SHEET_TITLE },
backgroundColor: Constants.SHEET_BACKGROUND_COLOR
}
)
.backgroundColor(this.bgColor)
}
@Builder
myBuilder() {
}
}
@Component
export default struct Reader {
@Consume('bgColor') @Watch('onPageChange') bgColor: string;
@Consume('fontSize') @Watch('onPageChange') fontSize: number;
@Consume('turnStyle') turnStyle: FlipPageType;
@Consume('screenW') screenW: number;
@Consume('screenH') screenH: number;
@Consume('rowGap') rowGap: number;
@Consume('sumRow') sumRow: number
@Consume('rowWord') rowWord: number;
@Prop @Watch('onPageChange') startIndex: number = 0;
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
private wordWidth: number = 0;
private wordHeight: number = 0;
aboutToAppear(): void {
this.drawText(this.startIndex);
}
onPageChange() {
this.drawText(this.startIndex);
}
drawText(startIndex: number) {
this.wordWidth = this.fontSize;
this.wordHeight = this.fontSize;
this.context.fillStyle = this.bgColor;
this.context.fillRect(0, 0, this.screenW, this.screenH);
this.context.fillStyle = Color.Black;
this.context.font = vp2px(this.fontSize) + Constants.CANVAS_FONT_SET;
if (startIndex < 0) {
startIndex = 0;
}
let gap = ((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) - this.wordWidth * this.rowWord) / (this.rowWord - 1);
let realRowGap = (this.screenH - this.sumRow * (this.wordHeight + this.rowGap)) / (this.sumRow - 1);
let currentX = Constants.SCREEN_MARGIN_LEFT;
let currentY = this.wordHeight;
for (let i = startIndex;; i++) {
if (currentX + this.wordWidth > this.screenW - (Constants.SCREEN_MARGIN_LEFT - 1)) {
currentX = Constants.SCREEN_MARGIN_LEFT;
currentY = currentY + this.rowGap + this.wordHeight + realRowGap;
if (currentY > this.screenH) {
break;
}
}
this.context.fillText(Constants.TEXT.charAt(i % Constants.TEXT.length), currentX, currentY);
currentX += this.wordWidth + gap;
}
}
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
Column() {
Canvas(this.context)
.width(Constants.FULL_PERCENT)
.height(Constants.FULL_PERCENT)
.onReady(() => {
this.drawText(this.startIndex);
})
}
.width(Constants.FULL_PERCENT)
}
.height(Constants.FULL_PERCENT)
}
}
@Component
export struct SlideFlipView {
@Consume('offsetX') offsetX: number;
@Consume('sumRow') sumRow: number;
@Consume('rowWord') rowWord: number;
@Consume('screenW') screenW: number;
@Consume('currentPageNum') currentPageNum: number;
@Link currentStartIndex: number;
private isFirst: boolean = false;
build() {
Stack() {
Reader({ startIndex: this.currentStartIndex + this.sumRow * this.rowWord })
.translate({ x: this.offsetX >= 0 ? this.screenW : this.screenW + this.offsetX, y: 0, z: 0 })
Reader({ startIndex: this.currentStartIndex })
.translate({ x: this.offsetX, y: 0, z: 0 })
.width(this.screenW)
Reader({ startIndex: this.currentStartIndex - this.sumRow * this.rowWord })
.translate({ x: this.offsetX >= 0 ? -this.screenW + this.offsetX : -this.screenW, y: 0, z: 0 })
}
.gesture(
PanGesture()
.onActionUpdate((event?: GestureEvent) => {
if (!event) {
return;
}
if (this.currentPageNum <= 1 && event.offsetX > 0) {
this.isFirst = true;
return;
}
this.offsetX = event.offsetX;
})
.onActionEnd(() => {
animateTo({
duration: Constants.FLIP_DURATION,
curve: Curve.EaseOut,
onFinish: () => {
if (this.offsetX > 0) {
this.currentPageNum -= 1;
if (this.currentStartIndex !== 0) {
this.currentStartIndex -= this.sumRow * this.rowWord;
}
}
if (this.offsetX < 0) {
this.currentPageNum += 1;
this.currentStartIndex += this.sumRow * this.rowWord;
}
if (this.isFirst) {
promptAction.showToast({
message: Constants.MSG_FLIP_OVER,
duration: Constants.PROMPT_DURATION
});
this.isFirst = false;
}
this.offsetX = 0;
}
}, () => {
if (this.offsetX > 0) {
this.offsetX = this.screenW;
}
if (this.offsetX < 0) {
this.offsetX = -this.screenW;
}
})
})
)
}
}
5、HarmonyOS 清除缓存功能?
app中有清除缓存的需求功能,清除缓存和计算app内缓存大小需要怎么实现。
查询缓存用storageStatistics.getCurrentBundleStats()接口,清除文件缓存,需要调用context的cacheDir获取缓存,然后调用系统文件fs接口,判断是文件或者文件夹,再分别消除缓存https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-file-storage-statistics-V5#storagestatisticsgetcurrentbundlestats9 清理:
import fs from '@ohos.file.fs';
let cacheDir = context.cacheDir;
@Entry
@Component
struct Clear_cache {
clearCache() {
// let cacheDir = getContext(this).cacheDir
// fs.rmdirSync(cacheDir)
// console.log("delete !!!")
fs.listFile(cacheDir).then((filenames) => {
for (let i = 0;i < filenames.length; i++) {
// let dirPath = cacheDir+filenames[i]
let dirPath = ${cacheDir}/${filenames[i]}
// 判断是否文件夹
let isDirectory
try {
isDirectory = fs.statSync(dirPath).isDirectory()
}
catch (e) {
console.log(e)
}
if (isDirectory) {
fs.rmdirSync(dirPath)
} else {
fs.unlink(dirPath).then(() => {
console.info("remove file succeed");
}).catch((err) => {
console.info("remove file failed with error message: " + err.message + ", error code: " + err.code);
});
}
}
})
}
}