把控件边缘描绘在屏幕上

神秘机师
249
·
3 个回应

最近有用户提到,想用 canvas 把控件的边缘描绘在屏幕上,挺有趣的,想到 Canvas 的文档比较简单,于是藉此做一个示例。

要实现这个想法,可以分成 2 个部分,一是寻找控件,二是描绘边界到屏幕。

环境:Hamibot v1.6.1,MIUI 13.0.14 Stable

寻找控件

这里用客户端日志这个界面作为例子,为了方便截图,这里会用到远程调试——设备调试

  1. 手机上打开 Hamibot,点击右上角图标(红圈所示)

点击右上角图标

  1. 进入到日志页面

日志页面

  1. 这里我们用“日志”这个控件为例,在搜索处输入“日志”,可以看到控件信息

控件信息

  1. 这个页面比较简单,“日志”只有一个,因此我们可以用 text().findOne() 获得控件的 bounds
let bounds = text('日志').findOne().bounds();
log(bounds);

控件信息

描绘到屏幕

现在,我们已经拿到了控件的 bounds 信息了,接下来就是画到屏幕上,这里我们会用到 floatycanvas

  1. 创建一个浮窗,并放置一个 canvas
let window = floaty.rawWindow(<canvas id="canvas" />);
window.setSize(-1, -1); // 全屏
window.setTouchable(false);
setInterval(() => {}, 1000);
  1. 有了 canvas,我们还需要一个 paint
let paint = new Paint();
paint.setStyle(Paint.Style.STROKE); // 我们是想描边,因此设置为 STROKE
paint.setStrokeWidth(6); // 为了看起来明显一些,我们用粗一些的线
paint['setColor(int)'](colors.parseColor('#00ff00')); // 这里用绿色
  1. 现在我们可以绘制了,这里我们用 drawRect 绘制矩形
window.canvas.on('draw', function (canvas) {
  canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.bottom, paint);
});

描绘边缘-偏移

可以看到屏幕上有绿色的线框了,但是位置向下偏移了,通过给 canvas 设置背景色,这里用粉色

背景色

发现顶部的状态栏没有覆盖到,也就是说浮窗的位置不是在最顶部,所以出现了偏移,这里可以把 bounds 减去状态栏的高度来修正,或者让浮窗从顶部开始,不管是哪种方式,都需要知道状态栏的高度,这里我们用 context.getResources().getDimensionPixelSize(context.getResources().getIdentifier('status_bar_height', 'dimen', 'android')); 获取状态栏的高度

  1. 这里我们选择用 window.setPosition() 让浮窗在最顶部
// 获取状态栏高度
let statusBarHeight = context
  .getResources()
  .getDimensionPixelSize(
    context
      .getResources()
      .getIdentifier('status_bar_height', 'dimen', 'android')
  );
window.setPosition(0, -statusBarHeight);

描绘边缘

最终,线框在正确的位置上了

完整代码

auto.waitFor(); // 文档地址:https://docs.hamibot.com/reference/widgetsBasedAutomation
let bounds = text('日志').findOne().bounds();
log(bounds);
// 获取状态栏高度
let statusBarHeight = context
  .getResources()
  .getDimensionPixelSize(
    context
      .getResources()
      .getIdentifier('status_bar_height', 'dimen', 'android')
  );
let window = floaty.rawWindow(<canvas id="canvas" />);
window.setSize(-1, -1); // 全屏
window.setPosition(0, -statusBarHeight);
window.setTouchable(false);
setInterval(() => {}, 1000);
let paint = new Paint();
paint.setStyle(Paint.Style.STROKE); // 我们是想描边,因此设置为 STROKE
paint.setStrokeWidth(6); // 为了看起来明显一些,我们用粗一些的线
paint['setColor(int)'](colors.parseColor('#00ff00')); // 这里用绿色
window.canvas.on('draw', function (canvas) {
  canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.bottom, paint);
});

dgiij:清除画布可以用 canvas.drawColor(android.graphics.Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);

参考

https://docs.hamibot.com/reference/widgetsBasedAutomation
https://docs.hamibot.com/reference/floaty
https://docs.hamibot.com/reference/canvas
https://developer.android.com/reference/android/graphics/Canvas
https://developer.android.com/reference/android/content/res/Resources
https://juejin.cn/post/7112260991227789325

最后

虽然不是多复杂的功能,但是有些涉及到 android,因此少不了要查看 android 的文档,网上搜索时也可以尝试加入关键词 autojs,看是否有相关例子。

喜欢看到这类文章吗,欢迎点赞 ❤️

发布于 2024-08-09
更新于 2024-09-23
好文需要鼓励,点赞获取更新通知