diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index 711d92e1..e5372fe0 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -20,7 +20,8 @@ "http 模块请求相关方法支持 options.client 选项, 用于配置 OkHttpClient.Builder (如 followRedirects 等) _[`issue #454`](http://issues.autojs6.com/454)_", "runtime.(set/is)JavaPrimitiveWrap 方法, 用于设置或获取 Java 原始类型包装策略 _[`issue #435`](http://issues.autojs6.com/435)_", "autojs.(restart/exit) 方法, 用于重启或退出 AutoJs6 应用, 并支持应用重启时自动运行其参数指定的脚本 _[`issue #460`](http://issues.autojs6.com/460)_", - "UiObject#isShifted 方法, 用于检测控件位置变化", + "UiObject#isShifted 方法, 用于检测控件位置变化 _[`issue #469`](http://issues.autojs6.com/469)_", + "UiObject#snapshot 方法, 用于捕获控件当前状态 _[`issue #469`](http://issues.autojs6.com/469)_", "crash 全局方法, 用于测试崩溃报告页面", "structuredClone 全局方法, 用于深拷贝 JavaScript 对象 (参阅 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/structuredClone))", "等价系列选择器 (UiSelector#id/text/...) 及包含系列选择器 (UiSelector#xxxContains) 支持正则表达式参数", diff --git a/app/src/main/java/org/autojs/autojs/core/automator/UiObject.kt b/app/src/main/java/org/autojs/autojs/core/automator/UiObject.kt index 57f3921c..6bbf6b4f 100644 --- a/app/src/main/java/org/autojs/autojs/core/automator/UiObject.kt +++ b/app/src/main/java/org/autojs/autojs/core/automator/UiObject.kt @@ -559,27 +559,40 @@ open class UiObject( "${lastChild() ?: ""}" == "${other.lastChild()}" } - fun isShifted(other: UiObject) = bounds() == other.bounds() + // Captures current state; refreshing it won't affect the original. + // zh-CN: 捕获当前状态; 刷新它不会影响原始对象. + fun snapshot(): UiObject { + val raw = unwrap() + val rawCopy = AccessibilityNodeInfo.obtain(raw) + return UiObject(rawCopy, allocator, depth, indexInParent) + } - fun isShifted(other: UiObject, tolerance: Double): Boolean { - val a = bounds() - val b = other.bounds() - return when { - tolerance < 0 -> throw WrappedIllegalArgumentException( - "Argument \"tolerance\" ${tolerance.jsBrief()} for UiObject#isShifted must be greater than or equal to 0", - ) - tolerance < 1 -> (width() to height()).let { (w, h) -> - return@let abs(a.left - b.left) > tolerance * w - || abs(a.top - b.top) > tolerance * h - || abs(a.right - b.right) > tolerance * w - || abs(a.bottom - b.bottom) > tolerance * h - } - else -> let { - return@let abs(a.left - b.left) > tolerance - || abs(a.top - b.top) > tolerance - || abs(a.right - b.right) > tolerance - || abs(a.bottom - b.bottom) > tolerance + @JvmOverloads + fun isShifted(tolerance: Double = 0.0): Boolean { + val probe = snapshot() + try { + val a = probe.bounds() /* Before. */ + if (!probe.refresh()) return true + val b = probe.bounds() /* After. */ + return when { + tolerance < 0 -> throw WrappedIllegalArgumentException( + "Argument \"tolerance\" ${tolerance.jsBrief()} for UiObject#isShifted must be greater than or equal to 0", + ) + tolerance < 1 -> (width() to height()).let { (w, h) -> + return@let abs(a.left - b.left) > tolerance * w + || abs(a.top - b.top) > tolerance * h + || abs(a.right - b.right) > tolerance * w + || abs(a.bottom - b.bottom) > tolerance * h + } + else -> let { + return@let abs(a.left - b.left) > tolerance + || abs(a.top - b.top) > tolerance + || abs(a.right - b.right) > tolerance + || abs(a.bottom - b.bottom) > tolerance + } } + } finally { + probe.recycle() } } diff --git a/version.properties b/version.properties index 2d86a76e..296be6a0 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Sat Dec 27 21:41:16 CST 2025 -BUILD_TIME=1766842876384 +#Sat Dec 27 22:46:17 CST 2025 +BUILD_TIME=1766846777167 COMPILE_SDK_VERSION=36 IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_NDK_VERSION=26.1.10909125