|
资讯缩略图:
资讯发布日期:2025-09-29
资讯发布简介:AIWROK软件支持悬浮窗自由定位和拖拽功能
资讯关键词:AIWROK软件支持悬浮窗自由定位和拖拽功能
资讯所属分类:IT资讯
联系:
① 本信息收集于网络,如有不对的地方欢迎联系我纠正! ② 本信息免费收录,不存在价格的问题! ③ 如果您的网站也想这样出现在这里,请您加好友情链接,我当天会审核通过!
④友情链接关键字:软件网站分类目录 网址:http://www.postbbs.com/
资讯详细描述
 | |  |  | AIWROK软件支持悬浮窗自由定位和拖拽功能
- //通过floatUI创建悬浮窗
- //适用于ES5系统安卓 JavaScript引擎Rhino
- //基于AIWROK软件安卓开发框架
- //支持悬浮窗自由定位和拖拽功能
- //🍎交流QQ群711841924群一,苹果内测群,528816639
- if (!String.prototype.repeat) {
- String.prototype.repeat = function(count) {
- 'use strict';
- if (this == null) {
- throw new TypeError('can\'t convert ' + this + ' to object');
- }
- var str = String(this);
- count = +count;
- if (count != count) {
- count = 0;
- }
- if (count < 0) {
- throw new RangeError('repeat count must be non-negative');
- }
- if (count == Infinity) {
- throw new RangeError('repeat count must be less than infinity');
- }
- count = Math.floor(count);
- if (str.length == 0 || count == 0) {
- return '';
- }
- // 确保重复的字符串不会超出字符串长度限制
- if (str.length * count >= 1 << 28) {
- throw new RangeError('repeat count must not overflow maximum string size');
- }
- var rpt = '';
- for (var i = 0; i < count; i++) {
- rpt += str;
- }
- return rpt;
- };
- }
- // ES5兼容的String.prototype.padStart polyfill
- if (!String.prototype.padStart) {
- String.prototype.padStart = function(targetLength, padString) {
- targetLength = targetLength >> 0; // 转换为整数
- padString = String((typeof padString !== 'undefined' ? padString : ' '));
- if (this.length > targetLength) {
- return String(this);
- } else {
- targetLength = targetLength - this.length;
- if (targetLength > padString.length) {
- padString += padString.repeat(targetLength / padString.length); // 截断或重复填充字符串
- }
- return padString.slice(0, targetLength) + String(this);
- }
- };
- }
- /*
- 安卓可移动侧栏日志吐司
- 功能:
- 1. 可拖拽移动的侧栏悬浮窗
- 2. 支持日志信息实时显示
- 3. 支持展开/收起功能
- 4. 支持自定义日志颜色
- */
- // 定义侧栏日志悬浮窗构造函数
- function 侧栏日志() {
- this.screenHeight = 1920; // 默认屏幕高度
- this.screenWidth = 1080; // 默认屏幕宽度
- this.isExpanded = false; // 展开状态标志
- this.logs = []; // 日志数组
- this.maxLogs = 50; // 最大日志条数
- this.dragging = false; // 拖拽状态标志
- this.lastX = 0; // 上次触摸X坐标
- this.lastY = 0; // 上次触摸Y坐标
- }
- // 创建侧栏日志悬浮窗
- 侧栏日志.prototype.create = function() {
- try {
- // 检查floatUI是否可用
- if (typeof floatUI === 'undefined') {
- printl("❌ 错误:未找到floatUI库");
- return false;
- }
-
- // 创建floatUI实例
- var fui = new floatUI();
-
- // 获取实际屏幕尺寸
- try {
- if (context && context.getResources && context.getResources().getDisplayMetrics) {
- var metrics = context.getResources().getDisplayMetrics();
- this.screenHeight = metrics.heightPixels || 1920;
- this.screenWidth = metrics.widthPixels || 1080;
- printl("✅ 获取屏幕尺寸: " + this.screenWidth + "x" + this.screenHeight);
- } else {
- printl("⚠️ 无法获取屏幕尺寸,使用默认值");
- this.screenHeight = 1920; // 默认屏幕高度
- this.screenWidth = 1080; // 默认屏幕宽度
- }
- } catch(e) {
- printl("⚠️ 获取屏幕尺寸失败,使用默认值: " + e);
- this.screenHeight = 1920;
- this.screenWidth = 1080;
- }
-
- // 定义侧边栏宽度和高度
- var sidebarWidth = 100; // 更窄的侧边栏宽度
- var sidebarMinWidth = 30; // 更窄的收起时最小宽度
- var sidebarHeight = 100; // 固定小高度,不再依赖屏幕比例
-
- // 加载XML布局
- try {
- fui.loadXML(`
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="${sidebarWidth}dp"
- android:layout_height="${sidebarHeight}dp"
- android:background="#CC000000"
- android:orientation="vertical"
- android:id="main_container">
-
- <!-- 可拖动的标题栏 -->
- <LinearLayout
- android:id="title_bar"
- android:layout_width="match_parent"
- android:layout_height="35dp"
- android:background="#666666"
- android:orientation="horizontal"
- android:gravity="center_vertical">
-
- <!-- 拖动区域 -->
- <View
- android:layout_width="${sidebarMinWidth}dp"
- android:layout_height="match_parent"
- android:background="#444444"/>
-
- <!-- 标题文字(仅在展开时可见) -->
- <TextView
- android:id="title_text"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:text="运行日志"
- android:textColor="#FFFFFF"
- android:gravity="center"
- android:textSize="14sp"/>
-
- <!-- 关闭按钮(仅在展开时可见) -->
- <Button
- android:id="close_button"
- android:layout_width="30dp"
- android:layout_height="30dp"
- android:text="✕"
- android:textColor="#FFFFFF"
- android:background="#FF4444"
- android:textSize="14sp"
- android:padding="0dp"
- android:gravity="center"/>
- </LinearLayout>
-
- <!-- 日志显示区域(仅在展开时可见) -->
- <ScrollView
- android:id="log_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#111111">
-
- <TextView
- android:id="log_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textColor="#00FF00"
- android:textSize="11sp"
- android:padding="3dp"
- android:lineSpacingExtra="1dp"/>
- </ScrollView>
-
- <!-- 展开/收起按钮 -->
- <Button
- android:id="toggle_button"
- android:layout_width="match_parent"
- android:layout_height="25dp"
- android:text="≡"
- android:textColor="#FFFFFF"
- android:background="#555555"
- android:textSize="16sp"/>
- </LinearLayout>
- `);
- printl("✅ XML布局加载成功");
- } catch (xmlError) {
- printl("❌ XML布局加载失败: " + xmlError);
- return false;
- }
-
- // 保存UI实例
- this.ui = fui;
-
- // 保存宽度设置供toggleExpand方法使用
- this.sidebarWidth = sidebarWidth;
- this.sidebarMinWidth = sidebarMinWidth;
-
- // 获取UI元素
- try {
- this.titleBar = fui.findViewById("title_bar");
- this.titleText = fui.findViewById("title_text");
- this.logContainer = fui.findViewById("log_container");
- this.logText = fui.findViewById("log_text");
- this.toggleButton = fui.findViewById("toggle_button");
- this.closeButton = fui.findViewById("close_button"); // 获取关闭按钮
- this.mainContainer = fui.findViewById("main_container");
-
- // 检查关键元素是否存在
- var missingElements = [];
- if (!this.titleBar) missingElements.push("titleBar");
- if (!this.logText) missingElements.push("logText");
- if (!this.toggleButton) missingElements.push("toggleButton");
- if (!this.mainContainer) missingElements.push("mainContainer");
-
- if (missingElements.length > 0) {
- printl("⚠️ 缺失关键UI元素: " + missingElements.join(", "));
- } else {
- printl("✅ 所有UI元素获取成功");
- }
- } catch (findError) {
- printl("❌ 获取UI元素失败: " + findError);
- }
-
- // 设置初始位置(屏幕左侧)
- try {
- this.setPos(0, (this.screenHeight - 100) / 2);
- printl("✅ 初始位置设置成功");
- } catch (posError) {
- printl("❌ 设置初始位置失败: " + posError);
- }
-
- // 初始化事件
- try {
- this.initEvents();
- printl("✅ 事件初始化成功");
- } catch (eventError) {
- printl("❌ 事件初始化失败: " + eventError);
- }
-
- // 显示初始化日志
- this.log("✅ 侧栏日志已启动", "#00FF00");
-
- return true;
- } catch (e) {
- printl("❌ 创建侧栏日志失败: " + e);
- return false;
- }
- };
- // 初始化事件
- 侧栏日志.prototype.initEvents = function() {
- var self = this;
-
- // 设置拖拽事件 - 添加更完善的错误处理
- try {
- if (typeof View !== 'undefined' && typeof MotionEvent !== 'undefined' && this.titleBar && this.titleBar.setOnTouchListener) {
- this.titleBar.setOnTouchListener(new View.OnTouchListener({
- onTouch: function(view, event) {
- try {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- self.dragging = true;
- self.lastX = event.getRawX();
- self.lastY = event.getRawY();
- break;
- case MotionEvent.ACTION_MOVE:
- if (self.dragging) {
- var dx = event.getRawX() - self.lastX;
- var dy = event.getRawY() - self.lastY;
-
- // 获取当前位置
- var currentX = view.getX();
- var currentY = view.getY();
-
- // 计算新位置(考虑整个容器的位置)
- var newX = currentX + dx;
- var newY = currentY + dy;
-
- // 边界检查
- if (newX < 0) newX = 0;
- if (newY < 0) newY = 0;
- if (newX > self.screenWidth - (self.isExpanded ? self.sidebarWidth : self.sidebarMinWidth))
- newX = self.screenWidth - (self.isExpanded ? self.sidebarWidth : self.sidebarMinWidth);
- if (newY > self.screenHeight - 100)
- newY = self.screenHeight - 100;
-
- // 设置新位置
- self.setPos(newX, newY);
-
- // 更新上次触摸位置
- self.lastX = event.getRawX();
- self.lastY = event.getRawY();
- }
- break;
- case MotionEvent.ACTION_UP:
- self.dragging = false;
- break;
- }
- return true;
- } catch (touchError) {
- // 静默处理触摸事件错误,避免崩溃
- return false;
- }
- }
- }));
- } else {
- printl("⚠️ 无法设置拖拽事件,缺少必要组件");
- }
- } catch (touchSetupError) {
- printl("❌ 设置拖拽事件失败: " + touchSetupError);
- }
-
- // 展开/收起按钮点击事件
- try {
- if (this.toggleButton && this.toggleButton.setOnClickListener) {
- this.toggleButton.setOnClickListener(function() {
- try {
- self.toggleExpand();
- } catch (toggleError) {
- printl("❌ 执行展开/收起操作失败: " + toggleError);
- }
- });
- }
- } catch (toggleSetupError) {
- printl("❌ 设置展开/收起事件失败: " + toggleSetupError);
- }
-
- // 关闭按钮点击事件
- try {
- if (this.closeButton && this.closeButton.setOnClickListener) {
- this.closeButton.setOnClickListener(function() {
- try {
- self.close();
- } catch (closeError) {
- printl("❌ 执行关闭操作失败: " + closeError);
- }
- });
- }
- } catch (closeSetupError) {
- printl("❌ 设置关闭事件失败: " + closeSetupError);
- }
- };
- // 获取当前时间用于日志
- 侧栏日志.prototype.getCurrentTime = function() {
- var now = new Date();
- var hours = now.getHours().toString().padStart(2, '0');
- var minutes = now.getMinutes().toString().padStart(2, '0');
- var seconds = now.getSeconds().toString().padStart(2, '0');
- return hours + ':' + minutes + ':' + seconds;
- };
- // 切换展开/收起状态
- 侧栏日志.prototype.toggleExpand = function() {
- try {
- var self = this;
-
- // 记录当前状态变更(使用printl避免递归)
- printl("[" + self.getCurrentTime() + "] " + (self.isExpanded ? "🔽 侧栏正在收起" : "🔼 侧栏正在展开"));
- // 定义要设置的目标宽度 - 修复逻辑:当前展开时应该设置为收起宽度,当前收起时应该设置为展开宽度
- var targetWidth = this.isExpanded ? this.sidebarMinWidth : this.sidebarWidth;
-
- // 切换展开状态标志
- this.isExpanded = !this.isExpanded;
-
- // 确保在主线程中执行UI操作
- var uiOperation = function() {
- self.performToggleExpand(targetWidth);
- };
-
- // 尝试多种UI线程调度方案
- var threadScheduled = false;
-
- // 方案1: 使用context.runOnUiThread
- try {
- if (context && context.runOnUiThread) {
- // 使用ES5兼容的方式创建Runnable对象
- var runnable = {
- run: function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ UI线程执行失败: " + e);
- }
- }
- };
- context.runOnUiThread(runnable);
- threadScheduled = true;
- printl("✅ 使用context.runOnUiThread调度UI线程");
- }
- } catch (e) {
- printl("❌ 方案1: context.runOnUiThread失败: " + e);
- }
-
- // 方案2: 使用View.post (如果有任何View对象可用)
- if (!threadScheduled) {
- try {
- var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
- if (viewToUse && viewToUse.post) {
- viewToUse.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ View.post执行失败: " + e);
- }
- });
- threadScheduled = true;
- printl("✅ 使用View.post调度UI线程");
- }
- } catch (e) {
- printl("❌ 方案2: View.post失败: " + e);
- }
- }
-
- // 方案3: 尝试使用Handler (如果可用)
- if (!threadScheduled) {
- try {
- if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
- var handler = new Handler(Looper.getMainLooper());
- handler.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ Handler执行失败: " + e);
- }
- });
- threadScheduled = true;
- printl("✅ 使用Handler调度UI线程");
- }
- } catch (e) {
- printl("❌ 方案3: Handler失败: " + e);
- }
- }
-
- // 方案4: 直接执行作为最后备选 (可能会失败但提供降级方案)
- if (!threadScheduled) {
- printl("⚠️ 所有线程调度方案失败,尝试直接执行UI操作");
- try {
- uiOperation();
- } catch (directError) {
- printl("❌ 直接执行UI操作失败: " + directError);
- }
- }
- } catch (e) {
- printl("❌ 切换展开状态失败: " + e);
- }
- };
- // 执行UI操作的核心方法(应在主线程中调用)
- 侧栏日志.prototype.performToggleExpand = function(targetWidth) {
- try {
- var self = this;
-
- // 切换UI元素可见性
- if (!this.isExpanded) {
- // 收起状态
- if (this.titleText && typeof this.titleText.setVisibility === 'function') {
- try {
- this.titleText.setVisibility(View.GONE);
- } catch (e) {
- printl("❌ 设置titleText可见性失败: " + e);
- }
- }
- if (this.logContainer && typeof this.logContainer.setVisibility === 'function') {
- try {
- this.logContainer.setVisibility(View.GONE);
- } catch (e) {
- printl("❌ 设置logContainer可见性失败: " + e);
- }
- }
- if (this.closeButton && typeof this.closeButton.setVisibility === 'function') {
- try {
- this.closeButton.setVisibility(View.GONE); // 收起时隐藏关闭按钮
- } catch (e) {
- printl("❌ 设置closeButton可见性失败: " + e);
- }
- }
- } else {
- // 展开状态
- if (this.titleText && typeof this.titleText.setVisibility === 'function') {
- try {
- this.titleText.setVisibility(View.VISIBLE);
- } catch (e) {
- printl("❌ 设置titleText可见性失败: " + e);
- }
- }
- if (this.logContainer && typeof this.logContainer.setVisibility === 'function') {
- try {
- this.logContainer.setVisibility(View.VISIBLE);
- } catch (e) {
- printl("❌ 设置logContainer可见性失败: " + e);
- }
- }
- if (this.closeButton && typeof this.closeButton.setVisibility === 'function') {
- try {
- this.closeButton.setVisibility(View.VISIBLE); // 展开时显示关闭按钮
- } catch (e) {
- printl("❌ 设置closeButton可见性失败: " + e);
- }
- }
- }
-
- // 尝试多种方法来设置宽度,增加更多的备选方案
- var widthSetSuccessfully = false;
- var errorMessages = [];
-
- // 获取屏幕密度
- var getDensity = function() {
- try {
- if (context && context.getResources && context.getResources().getDisplayMetrics) {
- return context.getResources().getDisplayMetrics().density;
- }
- } catch (e) {
- printl("⚠️ 获取屏幕密度失败: " + e);
- }
- return 3; // 默认密度
- };
-
- // 方法1: 尝试通过FloatUI对象的可能方法
- try {
- if (this.ui && typeof this.ui.setLayoutWidth === 'function') {
- this.ui.setLayoutWidth(targetWidth);
- widthSetSuccessfully = true;
- printl("方法1: 使用setLayoutWidth设置宽度成功");
- }
- } catch (e) {
- errorMessages.push("方法1: " + (e.message || String(e)));
- }
-
- // 方法2: 尝试通过LayoutParams设置宽度
- if (!widthSetSuccessfully) {
- try {
- if (this.mainContainer && typeof this.mainContainer.getLayoutParams === 'function' &&
- typeof this.mainContainer.setLayoutParams === 'function') {
- var params = this.mainContainer.getLayoutParams();
- if (params) {
- // 尝试将dp转换为像素
- var pixelWidth = Math.round(targetWidth * getDensity());
-
- // 安全地设置宽度
- try {
- params.width = pixelWidth;
- this.mainContainer.setLayoutParams(params);
- widthSetSuccessfully = true;
- printl("方法2: 使用LayoutParams设置宽度成功");
- } catch (setParamsError) {
- errorMessages.push("方法2: " + (setParamsError.message || String(setParamsError)));
- }
- }
- }
- } catch (e) {
- errorMessages.push("方法2: " + (e.message || String(e)));
- }
- }
-
- // 方法3: 尝试直接设置视图宽度
- if (!widthSetSuccessfully) {
- try {
- if (this.mainContainer && typeof this.mainContainer.setWidth === 'function') {
- // 使用已经计算好的像素宽度
- var pixelWidth = Math.round(targetWidth * getDensity());
- this.mainContainer.setWidth(pixelWidth);
- widthSetSuccessfully = true;
- printl("方法3: 使用setWidth设置宽度成功");
- }
- } catch (e) {
- errorMessages.push("方法3: " + (e.message || String(e)));
- }
- }
-
- // 方法4: 尝试修改XML布局参数
- if (!widthSetSuccessfully) {
- try {
- if (this.ui && typeof this.ui.setLayoutParams === 'function') {
- // 尝试获取并修改FloatUI的布局参数
- var floatParams = (typeof this.ui.getLayoutParams === 'function') ? this.ui.getLayoutParams() : null;
- if (floatParams) {
- floatParams.width = Math.round(targetWidth * getDensity());
- this.ui.setLayoutParams(floatParams);
- widthSetSuccessfully = true;
- printl("方法4: 使用FloatUI.setLayoutParams设置宽度成功");
- }
- }
- } catch (e) {
- errorMessages.push("方法4: " + (e.message || String(e)));
- }
- }
-
- // 方法5: 尝试使用layout方法直接设置位置和大小
- if (!widthSetSuccessfully) {
- try {
- if (this.mainContainer && typeof this.mainContainer.layout === 'function') {
- var left = 0;
- var top = 0;
- try {
- left = this.mainContainer.getLeft();
- top = this.mainContainer.getTop();
- } catch (positionError) {
- // 使用默认位置
- }
- var pixelWidth = Math.round(targetWidth * getDensity());
- var height = 0;
- try {
- height = this.mainContainer.getHeight();
- } catch (heightError) {
- height = 100; // 默认高度
- }
- this.mainContainer.layout(left, top, left + pixelWidth, top + height);
- widthSetSuccessfully = true;
- printl("方法5: 使用layout方法设置宽度成功");
- }
- } catch (e) {
- errorMessages.push("方法5: " + (e.message || String(e)));
- }
- }
-
- // 尝试UI刷新方法
- if (widthSetSuccessfully) {
- try {
- if (this.ui && typeof this.ui.updateLayout === 'function') {
- this.ui.updateLayout();
- printl("UI布局已更新");
- } else if (this.mainContainer && typeof this.mainContainer.requestLayout === 'function') {
- this.mainContainer.requestLayout();
- printl("请求重新布局");
- } else if (this.mainContainer && typeof this.mainContainer.invalidate === 'function') {
- this.mainContainer.invalidate();
- printl("视图已刷新");
- }
- } catch (e) {
- printl("刷新布局失败: " + e);
- }
- }
-
- // 设置按钮文本
- if (this.toggleButton && typeof this.toggleButton.setText === 'function') {
- try {
- this.toggleButton.setText("≡");
- } catch (e) {
- printl("❌ 设置按钮文本失败: " + e);
- }
- }
-
- // 延迟100ms后记录状态更新,确保UI已更新
- setTimeout(function() {
- try {
- if (widthSetSuccessfully) {
- printl("✅ " + (self.isExpanded ? "侧栏已展开" : "侧栏已收起"));
- } else {
- // 只记录第一个错误信息,避免日志过多
- var mainError = errorMessages.length > 0 ? errorMessages[0] : "未知错误";
- printl(mainError);
- printl("⚠️ 侧栏" + (self.isExpanded ? "展开" : "收起") + "但宽度调整失败");
- }
- } catch (e) {
- // 静默处理日志错误
- }
- }, 100);
-
- return widthSetSuccessfully;
- } catch (e) {
- printl("❌ 执行切换展开/收起操作失败: " + e);
- return false;
- }
- };
- // 添加日志
- 侧栏日志.prototype.log = function(message, color) {
- try {
- // 生成时间戳
- var now = new Date();
- var timeStr = now.getHours().toString().padStart(2, '0') + ":" +
- now.getMinutes().toString().padStart(2, '0') + ":" +
- now.getSeconds().toString().padStart(2, '0');
-
- // 格式化日志条目
- var logEntry = "[" + timeStr + "] " + message;
-
- // 添加到日志数组
- this.logs.push({text: logEntry, color: color || "#00FF00"});
-
- // 限制日志数量
- if (this.logs.length > this.maxLogs) {
- this.logs.shift(); // 移除最早的日志
- }
-
- // 更新显示
- this.updateLogDisplay();
-
- // 同时打印到控制台
- printl(logEntry);
- } catch (e) {
- printl("❌ 添加日志失败: " + e);
- }
- };
- // 更新日志显示
- 侧栏日志.prototype.updateLogDisplay = function() {
- try {
- var self = this;
- var uiOperation = function() {
- self.performUpdateLogDisplay();
- };
-
- // 尝试多种UI线程调度方案
- var threadScheduled = false;
-
- // 方案1: 使用context.runOnUiThread
- try {
- if (context && context.runOnUiThread) {
- var runnable = {
- run: function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ UI线程执行日志更新失败: " + e);
- }
- }
- };
- context.runOnUiThread(runnable);
- threadScheduled = true;
- }
- } catch (e) {
- printl("❌ 方案1: context.runOnUiThread调度日志更新失败: " + e);
- }
-
- // 方案2: 使用View.post
- if (!threadScheduled) {
- try {
- var viewToUse = self.logText || self.logContainer || self.mainContainer;
- if (viewToUse && viewToUse.post) {
- viewToUse.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ View.post执行日志更新失败: " + e);
- }
- });
- threadScheduled = true;
- }
- } catch (e) {
- printl("❌ 方案2: View.post调度日志更新失败: " + e);
- }
- }
-
- // 方案3: 尝试使用Handler
- if (!threadScheduled) {
- try {
- if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
- var handler = new Handler(Looper.getMainLooper());
- handler.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ Handler执行日志更新失败: " + e);
- }
- });
- threadScheduled = true;
- }
- } catch (e) {
- printl("❌ 方案3: Handler调度日志更新失败: " + e);
- }
- }
-
- // 方案4: 直接执行作为最后备选
- if (!threadScheduled) {
- try {
- uiOperation();
- } catch (directError) {
- printl("❌ 直接执行日志更新失败: " + directError);
- }
- }
- } catch (e) {
- printl("❌ 更新日志显示失败: " + e);
- }
- };
- // 执行日志显示更新的核心方法(应在主线程中调用)
- 侧栏日志.prototype.performUpdateLogDisplay = function() {
- try {
- // 检查logText是否存在
- if (!this.logText || typeof this.logText.setText !== 'function') {
- printl("⚠️ 日志显示组件不可用");
- return;
- }
-
- // 构建日志文本
- var logText = "";
- var useHtml = false;
-
- // 尝试HTML格式
- try {
- if (typeof android.text.Html !== 'undefined' && typeof android.text.Html.fromHtml === 'function') {
- var htmlText = "";
- for (var i = 0; i < this.logs.length; i++) {
- var log = this.logs[i];
- var color = log.color || "#00FF00";
- htmlText += "<font color=\"" + color + "\">" + log.text + "</font><br/>";
- }
-
- try {
- var spanned = android.text.Html.fromHtml(htmlText);
- this.logText.setText(spanned);
- useHtml = true;
- printl("✅ 日志使用HTML格式显示");
- } catch (htmlError) {
- printl("⚠️ HTML格式化失败,回退到纯文本: " + htmlError);
- }
- }
- } catch (e) {
- printl("⚠️ HTML支持不可用: " + e);
- }
-
- // 如果HTML格式失败,使用纯文本格式
- if (!useHtml) {
- for (var i = 0; i < this.logs.length; i++) {
- logText += this.logs[i].text + "\n";
- }
-
- try {
- this.logText.setText(logText);
- printl("✅ 日志使用纯文本格式显示");
- } catch (textError) {
- printl("❌ 设置日志文本失败: " + textError);
- }
- }
-
- // 尝试滚动到底部
- var self = this;
- try {
- if (this.logContainer && typeof this.logContainer.post === 'function') {
- this.logContainer.post(function() {
- try {
- if (self.logContainer && typeof self.logContainer.fullScroll === 'function') {
- self.logContainer.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
- }
- } catch (scrollError) {
- // 静默处理滚动错误
- }
- });
- } else if (this.logContainer && typeof this.logContainer.fullScroll === 'function') {
- this.logContainer.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
- }
- } catch (e) {
- // 静默处理滚动错误
- }
- } catch (e) {
- printl("❌ 执行日志显示更新失败: " + e);
- }
- };
- // 设置悬浮窗位置
- 侧栏日志.prototype.setPos = function(x, y) {
- try {
- var self = this;
-
- // 参数验证
- if (typeof x !== 'number' || typeof y !== 'number') {
- printl("❌ setPos参数错误: x和y必须是数字");
- return false;
- }
-
- // 边界检查
- var currentWidth = this.isExpanded ? this.sidebarWidth : this.sidebarMinWidth;
- try {
- if (context && context.getResources && context.getResources().getDisplayMetrics) {
- var density = context.getResources().getDisplayMetrics().density;
- currentWidth *= density;
- }
- } catch (e) {
- currentWidth *= 3; // 使用默认密度倍数
- }
-
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x > this.screenWidth - currentWidth) x = this.screenWidth - currentWidth;
- if (y > this.screenHeight - 100) y = this.screenHeight - 100;
-
- // 使用printl避免递归调用
- printl("🔄 设置悬浮窗位置: x=" + x + ", y=" + y);
-
- // 定义UI操作函数
- var uiOperation = function() {
- self.performSetPos(x, y);
- };
-
- // 尝试多种UI线程调度方案
- var threadScheduled = false;
-
- // 方案1: 使用context.runOnUiThread
- try {
- if (context && context.runOnUiThread) {
- var runnable = {
- run: function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ UI线程执行位置设置失败: " + e);
- }
- }
- };
- context.runOnUiThread(runnable);
- threadScheduled = true;
- printl("✅ 使用context.runOnUiThread调度位置设置");
- }
- } catch (e) {
- printl("❌ 方案1: context.runOnUiThread调度位置设置失败: " + e);
- }
-
- // 方案2: 使用View.post
- if (!threadScheduled) {
- try {
- var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
- if (viewToUse && typeof viewToUse.post === 'function') {
- viewToUse.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ View.post执行位置设置失败: " + e);
- }
- });
- threadScheduled = true;
- printl("✅ 使用View.post调度位置设置");
- }
- } catch (e) {
- printl("❌ 方案2: View.post调度位置设置失败: " + e);
- }
- }
-
- // 方案3: 尝试使用Handler
- if (!threadScheduled) {
- try {
- if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
- var handler = new Handler(Looper.getMainLooper());
- handler.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ Handler执行位置设置失败: " + e);
- }
- });
- threadScheduled = true;
- printl("✅ 使用Handler调度位置设置");
- }
- } catch (e) {
- printl("❌ 方案3: Handler调度位置设置失败: " + e);
- }
- }
-
- // 方案4: 直接执行作为最后备选
- if (!threadScheduled) {
- printl("⚠️ 所有线程调度方案失败,尝试直接执行位置设置");
- try {
- uiOperation();
- } catch (directError) {
- printl("❌ 直接执行位置设置失败: " + directError);
- }
- }
-
- return true;
- } catch (e) {
- printl("❌ 设置位置失败: " + e);
- return false;
- }
- };
- // 执行设置位置的核心方法(应在主线程中调用)
- 侧栏日志.prototype.performSetPos = function(x, y) {
- try {
- var posSetSuccess = false;
-
- // 方案1: 尝试使用floatUI的setPos方法
- try {
- if (this.ui && this.ui.setPos) {
- this.ui.setPos(x, y);
- posSetSuccess = true;
- printl("✅ 方案1: 使用floatUI.setPos设置位置成功");
- }
- } catch (e) {
- printl("❌ 方案1: floatUI.setPos失败: " + e);
- }
-
- // 方案2: 尝试使用floatUI的setPosition方法
- if (!posSetSuccess) {
- try {
- if (this.ui && this.ui.setPosition) {
- this.ui.setPosition(x, y);
- posSetSuccess = true;
- printl("✅ 方案2: 使用floatUI.setPosition设置位置成功");
- }
- } catch (e) {
- printl("❌ 方案2: floatUI.setPosition失败: " + e);
- }
- }
-
- // 方案3: 尝试使用setX和setY方法(如果可用)
- if (!posSetSuccess) {
- try {
- if (this.ui && typeof this.ui.setX === 'function' && typeof this.ui.setY === 'function') {
- this.ui.setX(x);
- this.ui.setY(y);
- posSetSuccess = true;
- printl("✅ 方案3: 使用ui.setX/setY设置位置成功");
- }
- } catch (e) {
- printl("❌ 方案3: ui.setX/setY失败: " + e);
- }
- }
-
- // 方案4: 尝试通过mainContainer设置位置
- if (!posSetSuccess) {
- try {
- if (this.mainContainer && typeof this.mainContainer.setX === 'function' && typeof this.mainContainer.setY === 'function') {
- this.mainContainer.setX(x);
- this.mainContainer.setY(y);
- posSetSuccess = true;
- printl("✅ 方案4: 使用mainContainer.setX/setY设置位置成功");
- }
- } catch (e) {
- printl("❌ 方案4: mainContainer.setX/setY失败: " + e);
- }
- }
-
- // 方案5: 尝试通过直接访问mainContainer设置位置
- if (!posSetSuccess) {
- try {
- if (this.mainContainer && typeof this.mainContainer.layout === 'function' && typeof this.mainContainer.getWidth === 'function' && typeof this.mainContainer.getHeight === 'function') {
- this.mainContainer.layout(x, y, x + this.mainContainer.getWidth(), y + this.mainContainer.getHeight());
- posSetSuccess = true;
- printl("✅ 方案5: 使用layout方法设置位置成功");
- }
- } catch (e) {
- printl("❌ 方案5: layout方法失败: " + e);
- }
- }
-
- // 刷新UI确保位置更新生效
- if (posSetSuccess) {
- try {
- // 尝试多种刷新方法
- if (this.mainContainer) {
- if (typeof this.mainContainer.invalidate === 'function') {
- this.mainContainer.invalidate();
- }
- if (typeof this.mainContainer.requestLayout === 'function') {
- this.mainContainer.requestLayout();
- }
- }
- printl("✅ 位置设置刷新完成");
- } catch (refreshError) {
- printl("⚠️ 刷新位置时出错: " + refreshError);
- }
- } else {
- printl("⚠️ 位置设置完成但可能未生效");
- }
-
- return posSetSuccess;
- } catch (e) {
- printl("❌ 执行位置设置失败: " + e);
- return false;
- }
- };
- // 清空日志
- 侧栏日志.prototype.clearLogs = function() {
- try {
- // 清空日志数组
- this.logs = [];
-
- // 清空日志显示
- if (this.logText && this.logText.setText) {
- try {
- this.logText.setText("");
- } catch (setTextError) {
- printl("⚠️ 清空日志显示失败: " + setTextError);
- }
- }
-
- // 记录清空操作
- this.log("🗑️ 日志已清空", "#FF0000");
- return true;
- } catch (e) {
- printl("❌ 清空日志失败: " + e);
- return false;
- }
- };
- // 关闭悬浮窗
- 侧栏日志.prototype.close = function() {
- try {
- var self = this;
-
- // 使用printl避免递归调用
- printl("🔄 正在关闭侧栏日志悬浮窗...");
-
- // 定义UI操作函数
- var uiOperation = function() {
- self.performClose();
- };
-
- // 尝试多种UI线程调度方案
- var threadScheduled = false;
-
- // 方案1: 使用context.runOnUiThread
- try {
- if (context && context.runOnUiThread) {
- var runnable = {
- run: function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ UI线程执行关闭操作失败: " + e);
- }
- }
- };
- context.runOnUiThread(runnable);
- threadScheduled = true;
- printl("✅ 使用context.runOnUiThread调度关闭操作");
- }
- } catch (e) {
- printl("❌ 方案1: context.runOnUiThread调度关闭操作失败: " + e);
- }
-
- // 方案2: 使用View.post
- if (!threadScheduled) {
- try {
- var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
- if (viewToUse && typeof viewToUse.post === 'function') {
- viewToUse.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ View.post执行关闭操作失败: " + e);
- }
- });
- threadScheduled = true;
- printl("✅ 使用View.post调度关闭操作");
- }
- } catch (e) {
- printl("❌ 方案2: View.post调度关闭操作失败: " + e);
- }
- }
-
- // 方案3: 尝试使用Handler
- if (!threadScheduled) {
- try {
- if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
- var handler = new Handler(Looper.getMainLooper());
- handler.post(function() {
- try {
- uiOperation();
- } catch (e) {
- printl("❌ Handler执行关闭操作失败: " + e);
- }
- });
- threadScheduled = true;
- printl("✅ 使用Handler调度关闭操作");
- }
- } catch (e) {
- printl("❌ 方案3: Handler调度关闭操作失败: " + e);
- }
- }
-
- // 方案4: 直接执行作为最后备选
- if (!threadScheduled) {
- printl("⚠️ 所有线程调度方案失败,尝试直接执行关闭操作");
- try {
- uiOperation();
- } catch (directError) {
- printl("❌ 直接执行关闭操作失败: " + directError);
- }
- }
- } catch (e) {
- printl("❌ 关闭侧栏日志悬浮窗失败: " + e);
- }
- };
- // 执行关闭操作的核心方法(应在主线程中调用)
- 侧栏日志.prototype.performClose = function() {
- try {
- printl("🔄 执行悬浮窗关闭操作...");
-
- // 尝试多种关闭方案
- var closeSuccess = false;
-
- // 方案1: 尝试使用close方法
- try {
- if (this.ui && typeof this.ui.close === 'function') {
- this.ui.close();
- closeSuccess = true;
- printl("✅ 方案1: 使用ui.close()成功关闭");
- }
- } catch (e) {
- printl("❌ 方案1: 使用ui.close()关闭失败: " + e);
- }
-
- // 方案2: 尝试使用destroy方法
- if (!closeSuccess) {
- try {
- if (this.ui && typeof this.ui.destroy === 'function') {
- this.ui.destroy();
- closeSuccess = true;
- printl("✅ 方案2: 使用ui.destroy()成功关闭");
- }
- } catch (e) {
- printl("❌ 方案2: 使用ui.destroy()关闭失败: " + e);
- }
- }
-
- // 方案3: 尝试从父容器移除
- if (!closeSuccess) {
- try {
- if (this.mainContainer && typeof this.mainContainer.getParent === 'function') {
- var parent = this.mainContainer.getParent();
- if (parent && typeof parent.removeView === 'function') {
- parent.removeView(this.mainContainer);
- closeSuccess = true;
- printl("✅ 方案3: 从父容器移除成功");
- }
- }
- } catch (e) {
- printl("❌ 方案3: 从父容器移除失败: " + e);
- }
- }
-
- // 方案4: 尝试隐藏视图
- if (!closeSuccess) {
- try {
- if (this.mainContainer && typeof this.mainContainer.setVisibility === 'function') {
- this.mainContainer.setVisibility(View.GONE);
- closeSuccess = true;
- printl("✅ 方案4: 隐藏视图成功");
- }
- } catch (e) {
- printl("❌ 方案4: 隐藏视图失败: " + e);
- }
- }
-
- // 清理资源
- try {
- // 清除事件监听器
- if (this.titleBar && typeof this.titleBar.setOnTouchListener === 'function') {
- this.titleBar.setOnTouchListener(null);
- }
- if (this.toggleButton && typeof this.toggleButton.setOnClickListener === 'function') {
- this.toggleButton.setOnClickListener(null);
- }
- if (this.closeButton && typeof this.closeButton.setOnClickListener === 'function') {
- this.closeButton.setOnClickListener(null);
- }
-
- // 清除引用,帮助垃圾回收
- this.ui = null;
- this.mainContainer = null;
- this.titleBar = null;
- this.toggleButton = null;
- this.closeButton = null;
- this.titleText = null;
- this.logContainer = null;
- this.logText = null;
- this.logs = null;
-
- printl("✅ 资源清理完成");
- } catch (cleanupError) {
- printl("⚠️ 资源清理时出错: " + cleanupError);
- }
-
- // 更新状态
- sidebarLogger = null;
-
- // 记录关闭结果
- if (closeSuccess) {
- printl("✅ 侧栏日志悬浮窗已成功关闭");
- } else {
- printl("⚠️ 侧栏日志悬浮窗尝试关闭,但可能未完全成功");
- }
-
- return closeSuccess;
- } catch (e) {
- printl("❌ 执行关闭操作失败: " + e);
- return false;
- }
- };
- // 创建并启动侧栏日志悬浮窗
- var sidebarLogger = null;
- // 版本信息
- const SIDEBAR_LOGGER_VERSION = "1.2.0";
- // 初始化悬浮窗
- function initSidebarLogger(options) {
- try {
- // 防止重复初始化
- if (sidebarLogger) {
- printl("⚠️ 侧栏日志已经初始化,无需重复创建");
- return sidebarLogger;
- }
-
- // 合并默认选项和用户选项
- options = options || {};
-
- // 环境检查
- if (typeof floatUI === 'undefined') {
- printl("❌ 错误:未找到floatUI库,请确保在AIWROK环境中运行!");
- return null;
- }
-
- // 打印启动信息
- printl("====================================");
- printl("🔄 侧栏日志悬浮窗初始化中...");
- printl("📱 版本: " + SIDEBAR_LOGGER_VERSION);
- printl("====================================");
-
- // 创建悬浮窗实例
- sidebarLogger = new 侧栏日志();
-
- // 创建悬浮窗
- if (sidebarLogger.create()) {
- printl("✅ 侧栏日志悬浮窗已创建成功!");
-
- // 添加欢迎日志
- sidebarLogger.log("🎉 欢迎使用侧栏日志工具", "#00FFFF");
- sidebarLogger.log("📱 版本: " + SIDEBAR_LOGGER_VERSION, "#00FFFF");
- sidebarLogger.log("💡 点击≡按钮展开/收起侧栏", "#FFFF00");
- sidebarLogger.log("🔄 拖动标题栏可移动悬浮窗", "#FFFF00");
- sidebarLogger.log("🗑️ 右上角关闭按钮可关闭悬浮窗", "#FFFF00");
- sidebarLogger.log("💡 可使用sidebarLogger.log()添加自定义日志", "#00FF00");
-
- // 自动展开悬浮窗,让用户看到关闭按钮
- try {
- setTimeout(function() {
- if (sidebarLogger && typeof sidebarLogger.toggleExpand === 'function') {
- sidebarLogger.toggleExpand();
- }
- }, 500);
- } catch (autoExpandError) {
- printl("⚠️ 自动展开失败: " + autoExpandError);
- }
-
- return sidebarLogger;
- } else {
- printl("❌ 侧栏日志悬浮窗创建失败!");
- sidebarLogger = null;
- return null;
- }
- } catch (e) {
- printl("❌ 初始化侧栏日志失败: " + e);
- sidebarLogger = null;
- return null;
- }
- }
- // 安全获取侧栏日志实例
- function getSidebarLogger() {
- return sidebarLogger;
- }
- // 安全地记录日志(即使悬浮窗未初始化也不会报错)
- function safeLog(message, color) {
- if (sidebarLogger && typeof sidebarLogger.log === 'function') {
- try {
- sidebarLogger.log(message, color);
- return true;
- } catch (e) {
- printl("⚠️ 记录日志失败: " + e);
- }
- }
- // 降级到console.log
- printl(message || "");
- return false;
- }
- // 启动悬浮窗
- try {
- // 延迟初始化,确保环境准备就绪
- setTimeout(function() {
- initSidebarLogger();
- }, 100);
- } catch (startupError) {
- printl("❌ 启动悬浮窗失败: " + startupError);
- // 作为最后的备选,尝试直接初始化
- try {
- initSidebarLogger();
- } catch (finalError) {
- printl("❌ 直接初始化也失败: " + finalError);
- }
- }
复制代码
| |  | |  |
|
untoAIWROK软件安卓工具箱悬浮窗next安卓toast吐司的各种方法应用实例
|