// 文档地址 https://docs.hamibot.com/

// 获取 RecyclerView 控件
var recyclerView = className('androidx.recyclerview.widget.RecyclerView')
.findOne();

if (recyclerView != null) {
// 获取当前可见的 item 数量
var itemCount = recyclerView.childCount();

// 遍历每个 item
for (var i = 0; i < itemCount; i++) {
    var item = recyclerView.getChild(i);
    
    // 在 item 中查找 id 为 tv_text 的 TextView
    var textView = item.findOne(id('tv_text'));
    
    if (textView != null) {
        var text = textView.text();
        log('第' + i + '个商品:' + text);
        
        // 获取其他商品信息(根据实际控件调整)
        var priceView = item.findOne(id('tv_price'));
        if (priceView != null) {
            log('价格:' + priceView.text());
        }
    }
}

// 向下滑动加载更多
recyclerView.scrollForward();
sleep(1000);

} 其中 // 在 item 中查找 id 为 tv_text 的 TextView
var textView = item.findOne(id('tv_text')); 报没有findOne这个函数

httnhktvzw · 11 小时前

回答

Hamibot AI
1
· 11 小时前

出现这个错误是因为 findOne()UiSelector(选择器)的方法,而不是 UiObject(控件对象)的方法。recyclerView.getChild(i) 获取到的是 UiObject 对象,该对象不支持直接调用 findOne() 来查找子控件。

要在 UiObject 内部查找特定 ID 的子控件,你需要遍历该对象的所有子控件进行匹配,或者直接使用全局选择器查找。针对 RecyclerView 的场景,建议遍历子控件。

以下是修正后的代码,兼容 Rhino 1.7.15 引擎(不使用箭头函数),并增加了稳定性处理:

// 文档地址 https://docs.hamibot.com/
auto.waitFor();

// 获取 RecyclerView 控件,建议加上 scrollable() 确保识别为可滚动列表
var recyclerView = className('androidx.recyclerview.widget.RecyclerView')
    .scrollable()
    .findOne();

if (recyclerView != null) {
    // 获取当前可见的 item 数量
    var itemCount = recyclerView.childCount();
    
    // 遍历每个可见的 item
    for (var i = 0; i < itemCount; i++) {
        var item = recyclerView.getChild(i);
        
        if (item == null) {
            continue;
        }
        
        // 遍历 item 的子控件查找 id 为 tv_text 的 TextView
        var textView = null;
        var children = item.children();
        
        if (children != null) {
            for (var j = 0; j < children.size(); j++) {
                var child = children.get(j);
                // 检查 id 是否匹配
                if (child.id() == 'tv_text') {
                    textView = child;
                    break;
                }
            }
        }
        
        if (textView != null) {
            var text = textView.text();
            log('第' + i + '个商品:' + text);
            
            // 获取其他商品信息(同样需要遍历查找)
            var priceView = null;
            if (children != null) {
                for (var k = 0; k < children.size(); k++) {
                    var child = children.get(k);
                    if (child.id() == 'tv_price') {
                        priceView = child;
                        break;
                    }
                }
            }
            
            if (priceView != null) {
                log('价格:' + priceView.text());
            }
        }
    }
    
    // 向下滑动加载更多
    recyclerView.scrollForward();
    sleep(1000);
} else {
    log('未找到 RecyclerView 控件');
}

修改要点说明:

  1. 查找方式变更:移除了 item.findOne(),改为通过 item.children() 获取子控件列表,然后循环比对 id() 属性。
  2. 选择器优化:给 RecyclerView 的选择器添加了 .scrollable(),这有助于更准确地定位可滚动列表控件,符合 Hamibot 的最佳实践。
  3. 空值检查:增加了 item == nullchildren != null 的判断,防止因控件加载未完成导致的脚本崩溃。
  4. 兼容性:代码中全部使用 var 和传统 for 循环,避免使用箭头函数 =>let/const,确保在 Rhino 1.7.15 引擎下稳定运行。

注意事项:

  • RecyclerViewgetChild(i) 只能获取当前屏幕可见的条目。如果需要遍历所有数据,需要结合 scrollForward() 循环滑动并记录已处理的内容,避免重复。
  • 控件的 id() 可能为空字符串,确保目标控件在布局文件中确实设置了 android:id="@+id/tv_text"
ℹ️ 本回答由 AI 生成,内容仅供参考