使用控件的所有信息获得控件的边距然后获得中心坐标并且点击

已存档
wrekemdkwh · 2 个月前
第 1 条补充
·
2 个月前

如果要获取没有id没有classname的控件中心坐标怎么写代码

第 2 条补充
·
2 个月前

如何通过父控件定位子控件

回答

Hamibot AI
1
· 2 个月前

要使用控件的所有信息获取边距并点击中心坐标,你可以按照以下步骤操作:

  1. 首先通过选择器找到目标控件
  2. 使用bounds()方法获取控件的边界信息
  3. 通过Rect对象的centerX()和centerY()方法获取中心坐标
  4. 使用click()函数点击该坐标

示例代码:

// 文档地址 https://docs.hamibot.com/
// 获取文本为"确定"的按钮并点击其中心
var button = text("确定").findOne();
var bounds = button.bounds();

// 显示边界信息(可选)
toast("左:" + bounds.left + ", 上:" + bounds.top +
", 右:" + bounds.right + ", 下:" + bounds.bottom);

// 点击控件中心
click(bounds.centerX(), bounds.centerY());

// 如果需要root权限点击,可以使用:
// Tap(bounds.centerX(), bounds.centerY());

// 也可以直接一步完成:
// click(text("确定").findOne().bounds().centerX(),
// text("确定").findOne().bounds().centerY());

Rect对象提供了以下有用的属性和方法:

  • left: 控件左边缘X坐标
  • top: 控件上边缘Y坐标
  • right: 控件右边缘X坐标
  • bottom: 控件下边缘Y坐标
  • centerX(): 返回控件中心X坐标
  • centerY(): 返回控件中心Y坐标
  • width(): 返回控件宽度
  • height(): 返回控件高度

如果脚本需要在不同分辨率设备上运行,记得使用setScreenMetrics()设置设计时的分辨率,这样坐标会自动适配。


补充回答 1

// 文档地址 https://docs.hamibot.com/
当你需要获取没有id和classname的控件中心坐标时,可以尝试以下几种方法:

方法1:通过文本定位(如果控件有显示文本)

var widget = text("要查找的文本内容").findOne();
var centerX = widget.bounds().centerX();
var centerY = widget.bounds().centerY();
toast("控件中心坐标: (" + centerX + ", " + centerY + ")");

方法2:通过描述定位(如果控件有描述属性)

var widget = desc("要查找的描述内容").findOne();
var centerX = widget.bounds().centerX();
var centerY = widget.bounds().centerY();
toast("控件中心坐标: (" + centerX + ", " + centerY + ")");

方法3:通过父控件定位子控件

// 先找到有特征的父控件
var parentWidget = text("父控件的文本").findOne();
// 获取第一个子控件(根据实际情况调整索引)
var childWidget = parentWidget.child(0);
var centerX = childWidget.bounds().centerX();
var centerY = childWidget.bounds().centerY();
toast("子控件中心坐标: (" + centerX + ", " + centerY + ")");

方法4:通过属性组合定位

// 利用其他属性组合定位,如包名+文本+可见性等
var widget = packageName("com.example.app").text("部分文本").visibleToUser(true).findOne();
var centerX = widget.bounds().centerX();
var centerY = widget.bounds().centerY();
toast("中心坐标: (" + centerX + ", " + centerY + ")");

方法5:使用布局分析工具辅助

  1. 在Hamibot中开启"布局分析"
  2. 点击目标控件,查看它的所有属性
  3. 根据显示的属性编写选择器
  4. 使用bounds()获取坐标

获取到控件后,通过bounds().centerX()bounds().centerY()即可获得中心坐标,这些坐标可以直接用于click()等操作:

// 获取控件并点击其中心位置
var widget = text("目标文本").findOne();
click(widget.bounds().centerX(), widget.bounds().centerY());

如果脚本需要在不同分辨率设备上运行,记得先调用setScreenMetrics(设计时的宽度, 设计时的高度)来设置屏幕适配。


补充回答 2

// 文档地址 https://docs.hamibot.com/
在Hamibot中通过父控件定位子控件是处理复杂界面布局的常用技巧,特别是当目标控件本身没有明显特征(如id、text等)时。以下是几种常用方法:

方法1:通过父控件特征定位特定位置的子控件

// 先找到具有明显特征的父控件
var parentWidget = id("parent_id").findOne(); // 也可以使用text、desc等定位父控件

// 获取第一个子控件(索引从0开始)
var firstChild = parentWidget.child(0);
// 获取第二个子控件
var secondChild = parentWidget.child(1);

// 点击第一个子控件的中心位置
click(firstChild.bounds().centerX(), firstChild.bounds().centerY());

方法2:遍历所有子控件并筛选

// 获取具有明显特征的父控件
var parentWidget = text("父控件文本").findOne();

// 遍历所有子控件
for (var i = 0; i < parentWidget.childCount(); i++) {
    var child = parentWidget.child(i);
    
    // 检查子控件是否符合特定条件
    if (child.bounds().height() > 100 && child.className() === "android.widget.ImageView") {
        // 找到目标子控件
        log("找到符合条件的子控件,位置: " + i);
        click(child.bounds().centerX(), child.bounds().centerY());
        break;
    }
}

方法3:使用children()方法结合筛选条件

// 获取父控件
var parentWidget = className("android.widget.LinearLayout").text("标题栏").findOne();

// 获取所有子控件并筛选
var children = parentWidget.children();
children.forEach(function(child, index) {
    log("子控件 " + index + " 类名: " + child.className());
    
    // 示例:点击所有文本控件
    if (child.className() === "android.widget.TextView" && child.text().includes("确定")) {
        click(child.bounds().centerX(), child.bounds().centerY());
    }
});

方法4:通过子控件数量和位置关系定位

// 有些情况下,可以根据子控件数量和相对位置来定位
var parentWidget = id("toolbar").findOne();

// 假设我们需要找到最后一个子控件
var lastChildIndex = parentWidget.childCount() - 1;
var lastChild = parentWidget.child(lastChildIndex);

// 或者找到倒数第二个子控件
if (parentWidget.childCount() >= 2) {
    var secondLastChild = parentWidget.child(parentWidget.childCount() - 2);
    click(secondLastChild.bounds().centerX(), secondLastChild.bounds().centerY());
}

方法5:多层父控件嵌套定位

// 当需要多层嵌套定位时
var grandParent = text("主界面").findOne();
var parent = grandParent.child(1); // 获取孙子层级的父控件
var targetChild = parent.child(2);  // 获取目标子控件

// 或者链式调用
var targetChild = text("主界面").findOne().child(1).child(2);
click(targetChild.bounds().centerX(), targetChild.bounds().centerY());

实际应用示例:定位并点击微信聊天界面的发送按钮

// 微信聊天界面中,发送按钮通常在输入框父控件的最后一个子控件
var inputBar = id("com.tencent.mm:id/apv").findOne(); // 输入框所在父控件
var childCount = inputBar.childCount();

// 假设发送按钮是最后一个子控件
var sendButton = inputBar.child(childCount - 1);
if (sendButton) {
    click(sendButton.bounds().centerX(), sendButton.bounds().centerY());
    toast("已点击发送按钮");
} else {
    toast("未找到发送按钮");
}

注意事项:

  1. 有些控件可能由于布局原因无法直接获取子控件,返回null
  2. 子控件索引从0开始,child(0)表示第一个子控件
  3. 在复杂布局中,可以结合bounds()属性来判断子控件的位置关系
  4. 如果需要在不同分辨率设备上运行,先调用setScreenMetrics(设计时的宽度, 设计时的高度)设置屏幕适配

使用这些方法,你可以有效地通过父控件定位那些本身没有id或classname的子控件,从而实现更精准的自动化操作。

ℹ️ 本回答由 AI 生成,内容仅供参考