HarmonyOS 鸿蒙Next Canvas如何触发刷新重复绘制?
HarmonyOS 鸿蒙Next Canvas如何触发刷新重复绘制?
Canvas如何触发刷新重复绘制?
更多关于HarmonyOS 鸿蒙Next Canvas如何触发刷新重复绘制?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
同问,变化时有日志,但是Canvas没刷新;
06-28 10:47:55.820 41283-41290 C01C10/ImsaKit com.huifu...merchant I [nodict]line: 864, function: DeleteLeft,length: 1
06-28 10:47:55.820 41283-41283 A03D00/JSAPP com.huifu...merchant I this.inputText deleteLeft this.inputText===125 length1
06-28 10:47:55.820 41283-41283 A01111/hlmMerchantTag com.huifu...merchant D HlmPwdTextInput onReady 290 42
06-28 10:47:55.820 41283-41283 A01111/hlmMerchantTag com.huifu...merchant D 31.666666666666668 51.66666666666667 41
06-28 10:47:55.822 41283-41283 A01111/hlmMerchantTag com.huifu...merchant D HlmPwdTextInput initDrawData offContext.save()
[@Component](/user/Component)
export struct HlmPwdTextInput {
[@Link](/user/Link) inputStr: string
//订死宽高,让外部自己设置大小?
static inputWidth: number = 290
static inputHeight: number = 42
onCompleted?: (inputStr: string) => void;
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
private offCanvas: OffscreenCanvas = new OffscreenCanvas(290, 42);
private lineWidth: number = 0;
private lineAndSpace: number = 0;
private lineTopMargin: number = 0;
//软键盘
inputController?: inputMethod.InputMethodController
isAttached: boolean = false;
keyboardStatus: inputMethod.KeyboardStatus = inputMethod.KeyboardStatus.NONE;
build() {
Column() {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
this.drawInput();
})
}
.backgroundColor('#9f9')
.width(HlmPwdTextInput.inputWidth)
.height(HlmPwdTextInput.inputHeight)
.onTouch(() => {
this.attachAndListener();
})
}
drawInput() {
this.initDrawData();
let offContext = this.offCanvas.getContext("2d", this.settings);
offContext.clearRect(0, 0, HlmPwdTextInput.inputWidth, HlmPwdTextInput.inputHeight);
//中心文字
offContext.strokeStyle = '#999999';
offContext.lineWidth = 1;
offContext.beginPath();
for (let index = 0; index < 6; index++) {
offContext.moveTo(index * (this.lineAndSpace), this.lineTopMargin);
offContext.lineTo(this.lineWidth + index * (this.lineAndSpace), this.lineTopMargin);
offContext.closePath();
offContext.stroke();
}
offContext.fillStyle = '#333333';
for (let index = 0; index < this.inputStr.length; index++) {
const x = this.lineWidth / 2 + index * (this.lineAndSpace);
const y = HlmPwdTextInput.inputHeight / 2;
offContext.moveTo(x, y);
offContext.arc(x, y, 6, 0, Math.PI * 2);
offContext.fill();
}
offContext.save();
LogUtils.d(`HlmPwdTextInput initDrawData offContext.save()`)
let image = this.offCanvas.transferToImageBitmap()
this.context.transferFromImageBitmap(image)
}
aboutToAppear(): void {
this.inputController = inputMethod.getController();
}
aboutToDisappear(): void {
this.detach();
}
initDrawData() {
this.lineWidth = (HlmPwdTextInput.inputWidth - 5 * 20) / 6;
this.lineAndSpace = this.lineWidth + 20;
this.lineTopMargin = HlmPwdTextInput.inputHeight - 1;
LogUtils.d(`HlmPwdTextInput onReady ${HlmPwdTextInput.inputWidth} ${HlmPwdTextInput.inputHeight}
${this.lineWidth} ${this.lineAndSpace} ${this.lineTopMargin}`)
}
// 绑定和设置监听
async attachAndListener() {
// 输入法配置项
let textConfig: inputMethod.TextConfig = {
inputAttribute: {
textInputType: inputMethod.TextInputType.NUMBER,
enterKeyType: inputMethod.EnterKeyType.DONE
}
};
this.inputController?.attach(true, textConfig, (err, data) => {
LogUtils.d(`err=${err?.message || ''}; data: ${data}`)
})
// 控件绑定输入法
if (!this.isAttached) {
this.attachListener();
}
this.isAttached = true;
}
/**
* 订阅输入法回调
*/
attachListener(): void {
// 订阅输入法应用插入文本事件
this.inputController?.on('insertText', (text) => {
if (this.inputStr.length >= 6) {
setTimeout(() => {
if (this.onCompleted) {
this.onCompleted(this.inputStr);
}
}, 251);
return;
}
this.inputStr += text;
console.info("this.inputText", "insertText this.inputText===" + this.inputStr);
this.drawInput();
// this.context = new CanvasRenderingContext2D(this.settings);
})
// 订阅输入法应用向左删除事件
this.inputController?.on('deleteLeft', (length) => {
this.inputStr = this.inputStr.substring(0, this.inputStr.length - 1);
console.info("this.inputText", "deleteLeft this.inputText===" + this.inputStr, 'length' + length)
this.drawInput();
})
// 订阅输入法应用发送输入法软键盘状态事件
this.inputController?.on('sendKeyboardStatus', (keyboardStatus: inputMethod.KeyboardStatus) => {
this.keyboardStatus = keyboardStatus;
console.info("ImsaKit this.inputText keyboardStatus= " + this.keyboardStatus)
})
}
//解绑输入法
detach() {
this.inputController?.off('insertText');
this.inputController?.off('deleteLeft');
this.inputController?.off('sendKeyboardStatus');
this.inputController?.detach((err: BusinessError) => {
if (err) {
console.error(`Failed to detach: ${JSON.stringify(err)}`);
return;
}
this.isAttached = false
console.log('Succeeded in detaching inputMethod.');
});
}
}
笑死我了,欺骗下?写两次?
Column() {
if (this.inputStr.length % 2 == 0) {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
this.drawInput();
})
} else {
if (this.inputStr.length % 2 == 1) {
Canvas(this.context)
.width('100%')
.height('100%')
.onReady(() => {
this.drawInput();
})
}
}
}
.backgroundColor('#9f9')
.width(HlmPwdTextInput.inputWidth)
.height(HlmPwdTextInput.inputHeight)
.onTouch(() => {
this.attachAndListener();
})
在HarmonyOS鸿蒙Next中,Canvas触发刷新重复绘制通常涉及以下几种方法:
- 使用invalidate()方法:强制View重绘,会调用onDraw(Canvas canvas)方法,可以在这里更新绘图内容。
- 修改View的属性:如果自定义View的刷新依赖于某些属性的变化,可以通过修改这些属性的值来触发重绘或重新布局。
- 调用requestLayout()方法:如果需要重新布局,可以调用此方法,系统会安排一个布局传递过程,最终可能导致onLayout或onMeasure的调用,从而触发绘制更新。
在Canvas组件中,onReady()
事件回调是组件初始化完成时触发,可以在此回调中获取Canvas组件的确定宽高,并进一步使用CanvasRenderingContext2D对象或OffscreenCanvasRenderingContext2D对象调用相关API进行图形绘制。但请注意,onReady()
本身不直接用于触发刷新重复绘制,而是作为初始化绘制的入口点。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。