let timmer = floaty.window(
<frame>
<vertical padding="4" spacing="4">
<frame id="ctx">
<canvas id="canvas" w="300" h="100"/>
</frame>
</vertical>
</frame>
);
let canvas = timmer.canvas;
let ctx = canvas.getContext("2d");
function drawClock() {
let now = new Date();
let hours = String(now.getHours()).padStart(2, '0');
let minutes = String(now.getMinutes()).padStart(2, '0');
let seconds = String(now.getSeconds()).padStart(2, '0');
let randomNum = Math.floor(Math.random() * 10) + 1;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#000000";
ctx.font = "48px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
let timeText = `${hours}:${minutes}:${seconds}.${randomNum}`;
ctx.fillText(timeText, canvas.width/2, canvas.height/2);
}
// 保持悬浮窗不关闭
setInterval(()=>{}, 1000);
setInterval(drawClock, 1000);
// 初始绘制
ui.run(drawClock);
以上方法找不到android.view.View.getContext(String)
以上代码 Typeface 未定义
回答
问题原因:canvas.getContext("2d")
是Web端Canvas的调用方式,而Hamibot基于Android平台,使用的是原生Android Canvas对象,不存在getContext
方法。
解决方案:直接使用Android Canvas API进行绘制,以下是修正后的代码:
// 文档地址 https://docs.hamibot.com/
let timmer = floaty.window(
<frame>
<vertical padding="4" spacing="4">
<frame id="ctx">
<canvas id="canvas" w="300" h="100"/>
</frame>
</vertical>
</frame>
);
let canvas = timmer.canvas;
let paint = new Paint();
// 初始化画笔
paint.setTextSize(48);
paint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
paint.setTextAlign(Paint.Align.CENTER);
paint.setColor(colors.parseColor("#000000"));
function drawClock() {
let now = new Date();
let hours = String(now.getHours()).padStart(2, '0');
let minutes = String(now.getMinutes()).padStart(2, '0');
let seconds = String(now.getSeconds()).padStart(2, '0');
let randomNum = Math.floor(Math.random() * 10) + 1;
// 获取画布并清空
let currentCanvas = canvas.getCanvas();
if(!currentCanvas) return;
// 绘制背景(清除画布)
currentCanvas.drawColor(colors.parseColor("#FFFFFF"), android.graphics.PorterDuff.Mode.SRC_OVER);
// 绘制文本
let timeText = `${hours}:${minutes}:${seconds}.${randomNum}`;
currentCanvas.drawText(timeText, canvas.getWidth()/2, canvas.getHeight()/2, paint);
}
// 保持悬浮窗存活
setInterval(()=>{}, 1000);
// 定时更新(需在UI线程操作)
setInterval(()=>{
ui.run(drawClock);
}, 1000);
// 初始绘制
ui.run(drawClock);
关键修改点:
- 移除了
getContext("2d")
调用,直接使用canvas对象 - 创建
Paint
对象替代ctx样式设置 - 使用
canvas.getCanvas()
获取实际Canvas对象 - 用
drawText
代替fillText,使用drawColor
清除画布 - 所有绘制操作都通过
ui.run
保证在UI线程执行
注意事项:
- Android Canvas绘制需要手动处理画布状态
- 颜色值需要使用
colors.parseColor()
转换 - 文字对齐需要使用
Paint.Align.CENTER
替代textAlign - 每次绘制前需调用
getCanvas()
获取最新画布
补充回答 1
在 Hamibot 中使用 typeface
属性时无需手动定义 Typeface
对象。根据文档说明,直接通过字符串值指定字体类型即可完成设置。以下是正确用法示例:
// 文本控件直接声明 typeface 属性
<text text="等宽字体" typeface="monospace"/>
// 动态修改字体(假设控件 id 为 myText)
ui.myText.attr("typeface", "serif"); // 支持 normal/sans/serif/monospace
错误原因分析:
若出现 Typeface is not defined
错误,通常是因为尝试使用类似 Typeface.create()
的方法。注意:Hamibot 的 JavaScript 环境未暴露 Android 的 Typeface
类,所有字体设置应通过控件的 typeface
属性完成。