信息发布软件,b2b软件,广告发布软件

 找回密码
 立即注册
搜索
查看: 568|回复: 0
打印 上一主题 下一主题

[宣传软件网站动态] AIWROK软件支持悬浮窗自由定位和拖拽功能

[复制链接]

780

主题

864

帖子

5536

积分

积分
5536
跳转到指定楼层
宣传软件楼主
发表于 2025-9-29 08:08:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

资讯缩略图:

资讯发布日期:2025-09-29

资讯发布简介:AIWROK软件支持悬浮窗自由定位和拖拽功能

资讯关键词:AIWROK软件支持悬浮窗自由定位和拖拽功能

资讯所属分类:IT资讯 

联系:

① 本信息收集于网络,如有不对的地方欢迎联系我纠正!
② 本信息免费收录,不存在价格的问题!
③ 如果您的网站也想这样出现在这里,请您加好友情链接,我当天会审核通过!

④友情链接关键字:软件网站分类目录 网址:http://www.postbbs.com/

资讯详细描述
AIWROK软件支持悬浮窗自由定位和拖拽功能
AIWROK软件支持悬浮窗自由定位和拖拽功能 b2b软件

AIWROK软件支持悬浮窗自由定位和拖拽功能 b2b软件
  1. //通过floatUI创建悬浮窗
  2. //适用于ES5系统安卓 JavaScript引擎Rhino
  3. //基于AIWROK软件安卓开发框架
  4. //支持悬浮窗自由定位和拖拽功能
  5. //🍎交流QQ群711841924群一,苹果内测群,528816639


  6. if (!String.prototype.repeat) {
  7.     String.prototype.repeat = function(count) {
  8.         'use strict';
  9.         if (this == null) {
  10.             throw new TypeError('can\'t convert ' + this + ' to object');
  11.         }
  12.         var str = String(this);
  13.         count = +count;
  14.         if (count != count) {
  15.             count = 0;
  16.         }
  17.         if (count < 0) {
  18.             throw new RangeError('repeat count must be non-negative');
  19.         }
  20.         if (count == Infinity) {
  21.             throw new RangeError('repeat count must be less than infinity');
  22.         }
  23.         count = Math.floor(count);
  24.         if (str.length == 0 || count == 0) {
  25.             return '';
  26.         }
  27.         // 确保重复的字符串不会超出字符串长度限制
  28.         if (str.length * count >= 1 << 28) {
  29.             throw new RangeError('repeat count must not overflow maximum string size');
  30.         }
  31.         var rpt = '';
  32.         for (var i = 0; i < count; i++) {
  33.             rpt += str;
  34.         }
  35.         return rpt;
  36.     };
  37. }

  38. // ES5兼容的String.prototype.padStart polyfill
  39. if (!String.prototype.padStart) {
  40.     String.prototype.padStart = function(targetLength, padString) {
  41.         targetLength = targetLength >> 0; // 转换为整数
  42.         padString = String((typeof padString !== 'undefined' ? padString : ' '));
  43.         if (this.length > targetLength) {
  44.             return String(this);
  45.         } else {
  46.             targetLength = targetLength - this.length;
  47.             if (targetLength > padString.length) {
  48.                 padString += padString.repeat(targetLength / padString.length); // 截断或重复填充字符串
  49.             }
  50.             return padString.slice(0, targetLength) + String(this);
  51.         }
  52.     };
  53. }

  54. /*
  55.    安卓可移动侧栏日志吐司
  56.    功能:
  57.    1. 可拖拽移动的侧栏悬浮窗
  58.    2. 支持日志信息实时显示
  59.    3. 支持展开/收起功能
  60.    4. 支持自定义日志颜色
  61. */

  62. // 定义侧栏日志悬浮窗构造函数
  63. function 侧栏日志() {
  64.     this.screenHeight = 1920; // 默认屏幕高度
  65.     this.screenWidth = 1080;  // 默认屏幕宽度
  66.     this.isExpanded = false;  // 展开状态标志
  67.     this.logs = [];           // 日志数组
  68.     this.maxLogs = 50;        // 最大日志条数
  69.     this.dragging = false;    // 拖拽状态标志
  70.     this.lastX = 0;           // 上次触摸X坐标
  71.     this.lastY = 0;           // 上次触摸Y坐标
  72. }

  73. // 创建侧栏日志悬浮窗
  74. 侧栏日志.prototype.create = function() {
  75.     try {
  76.         // 检查floatUI是否可用
  77.         if (typeof floatUI === 'undefined') {
  78.             printl("❌ 错误:未找到floatUI库");
  79.             return false;
  80.         }
  81.         
  82.         // 创建floatUI实例
  83.         var fui = new floatUI();
  84.         
  85.         // 获取实际屏幕尺寸
  86.         try {
  87.             if (context && context.getResources && context.getResources().getDisplayMetrics) {
  88.                 var metrics = context.getResources().getDisplayMetrics();
  89.                 this.screenHeight = metrics.heightPixels || 1920;
  90.                 this.screenWidth = metrics.widthPixels || 1080;
  91.                 printl("✅ 获取屏幕尺寸: " + this.screenWidth + "x" + this.screenHeight);
  92.             } else {
  93.                 printl("⚠️ 无法获取屏幕尺寸,使用默认值");
  94.                 this.screenHeight = 1920; // 默认屏幕高度
  95.                 this.screenWidth = 1080;  // 默认屏幕宽度
  96.             }
  97.         } catch(e) {
  98.             printl("⚠️ 获取屏幕尺寸失败,使用默认值: " + e);
  99.             this.screenHeight = 1920;
  100.             this.screenWidth = 1080;
  101.         }
  102.         
  103.         // 定义侧边栏宽度和高度
  104.         var sidebarWidth = 100;  // 更窄的侧边栏宽度
  105.         var sidebarMinWidth = 30; // 更窄的收起时最小宽度
  106.         var sidebarHeight = 100; // 固定小高度,不再依赖屏幕比例
  107.         
  108.         // 加载XML布局
  109.         try {
  110.             fui.loadXML(`
  111.                 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  112.                     android:layout_width="${sidebarWidth}dp"
  113.                     android:layout_height="${sidebarHeight}dp"
  114.                     android:background="#CC000000"
  115.                     android:orientation="vertical"
  116.                     android:id="main_container">
  117.                     
  118.                     <!-- 可拖动的标题栏 -->
  119.                     <LinearLayout
  120.                         android:id="title_bar"
  121.                         android:layout_width="match_parent"
  122.                         android:layout_height="35dp"
  123.                         android:background="#666666"
  124.                         android:orientation="horizontal"
  125.                         android:gravity="center_vertical">
  126.                         
  127.                         <!-- 拖动区域 -->
  128.                         <View
  129.                             android:layout_width="${sidebarMinWidth}dp"
  130.                             android:layout_height="match_parent"
  131.                             android:background="#444444"/>
  132.                         
  133.                         <!-- 标题文字(仅在展开时可见) -->
  134.                         <TextView
  135.                             android:id="title_text"
  136.                             android:layout_width="0dp"
  137.                             android:layout_height="match_parent"
  138.                             android:layout_weight="1"
  139.                             android:text="运行日志"
  140.                             android:textColor="#FFFFFF"
  141.                             android:gravity="center"
  142.                             android:textSize="14sp"/>
  143.                            
  144.                         <!-- 关闭按钮(仅在展开时可见) -->
  145.                             <Button
  146.                                 android:id="close_button"
  147.                                 android:layout_width="30dp"
  148.                                 android:layout_height="30dp"
  149.                                 android:text="✕"
  150.                                 android:textColor="#FFFFFF"
  151.                                 android:background="#FF4444"
  152.                                 android:textSize="14sp"
  153.                                 android:padding="0dp"
  154.                                 android:gravity="center"/>
  155.                     </LinearLayout>
  156.                     
  157.                     <!-- 日志显示区域(仅在展开时可见) -->
  158.                     <ScrollView
  159.                         android:id="log_container"
  160.                         android:layout_width="match_parent"
  161.                         android:layout_height="match_parent"
  162.                         android:background="#111111">
  163.                         
  164.                         <TextView
  165.                             android:id="log_text"
  166.                             android:layout_width="match_parent"
  167.                             android:layout_height="wrap_content"
  168.                             android:textColor="#00FF00"
  169.                             android:textSize="11sp"
  170.                             android:padding="3dp"
  171.                             android:lineSpacingExtra="1dp"/>
  172.                     </ScrollView>
  173.                     
  174.                     <!-- 展开/收起按钮 -->
  175.                     <Button
  176.                         android:id="toggle_button"
  177.                         android:layout_width="match_parent"
  178.                         android:layout_height="25dp"
  179.                         android:text="≡"
  180.                         android:textColor="#FFFFFF"
  181.                         android:background="#555555"
  182.                         android:textSize="16sp"/>
  183.                 </LinearLayout>
  184.             `);
  185.             printl("✅ XML布局加载成功");
  186.         } catch (xmlError) {
  187.             printl("❌ XML布局加载失败: " + xmlError);
  188.             return false;
  189.         }
  190.         
  191.         // 保存UI实例
  192.         this.ui = fui;
  193.         
  194.         // 保存宽度设置供toggleExpand方法使用
  195.         this.sidebarWidth = sidebarWidth;
  196.         this.sidebarMinWidth = sidebarMinWidth;
  197.         
  198.         // 获取UI元素
  199.         try {
  200.             this.titleBar = fui.findViewById("title_bar");
  201.             this.titleText = fui.findViewById("title_text");
  202.             this.logContainer = fui.findViewById("log_container");
  203.             this.logText = fui.findViewById("log_text");
  204.             this.toggleButton = fui.findViewById("toggle_button");
  205.             this.closeButton = fui.findViewById("close_button"); // 获取关闭按钮
  206.             this.mainContainer = fui.findViewById("main_container");
  207.             
  208.             // 检查关键元素是否存在
  209.             var missingElements = [];
  210.             if (!this.titleBar) missingElements.push("titleBar");
  211.             if (!this.logText) missingElements.push("logText");
  212.             if (!this.toggleButton) missingElements.push("toggleButton");
  213.             if (!this.mainContainer) missingElements.push("mainContainer");
  214.             
  215.             if (missingElements.length > 0) {
  216.                 printl("⚠️ 缺失关键UI元素: " + missingElements.join(", "));
  217.             } else {
  218.                 printl("✅ 所有UI元素获取成功");
  219.             }
  220.         } catch (findError) {
  221.             printl("❌ 获取UI元素失败: " + findError);
  222.         }
  223.         
  224.         // 设置初始位置(屏幕左侧)
  225.         try {
  226.             this.setPos(0, (this.screenHeight - 100) / 2);
  227.             printl("✅ 初始位置设置成功");
  228.         } catch (posError) {
  229.             printl("❌ 设置初始位置失败: " + posError);
  230.         }
  231.         
  232.         // 初始化事件
  233.         try {
  234.             this.initEvents();
  235.             printl("✅ 事件初始化成功");
  236.         } catch (eventError) {
  237.             printl("❌ 事件初始化失败: " + eventError);
  238.         }
  239.         
  240.         // 显示初始化日志
  241.         this.log("✅ 侧栏日志已启动", "#00FF00");
  242.         
  243.         return true;
  244.     } catch (e) {
  245.         printl("❌ 创建侧栏日志失败: " + e);
  246.         return false;
  247.     }
  248. };

  249. // 初始化事件
  250. 侧栏日志.prototype.initEvents = function() {
  251.     var self = this;
  252.    
  253.     // 设置拖拽事件 - 添加更完善的错误处理
  254.     try {
  255.         if (typeof View !== 'undefined' && typeof MotionEvent !== 'undefined' && this.titleBar && this.titleBar.setOnTouchListener) {
  256.             this.titleBar.setOnTouchListener(new View.OnTouchListener({
  257.                 onTouch: function(view, event) {
  258.                     try {
  259.                         switch (event.getAction()) {
  260.                             case MotionEvent.ACTION_DOWN:
  261.                                 self.dragging = true;
  262.                                 self.lastX = event.getRawX();
  263.                                 self.lastY = event.getRawY();
  264.                                 break;
  265.                             case MotionEvent.ACTION_MOVE:
  266.                                 if (self.dragging) {
  267.                                     var dx = event.getRawX() - self.lastX;
  268.                                     var dy = event.getRawY() - self.lastY;
  269.                                     
  270.                                     // 获取当前位置
  271.                                     var currentX = view.getX();
  272.                                     var currentY = view.getY();
  273.                                     
  274.                                     // 计算新位置(考虑整个容器的位置)
  275.                                     var newX = currentX + dx;
  276.                                     var newY = currentY + dy;
  277.                                     
  278.                                     // 边界检查
  279.                                     if (newX < 0) newX = 0;
  280.                                     if (newY < 0) newY = 0;
  281.                                     if (newX > self.screenWidth - (self.isExpanded ? self.sidebarWidth : self.sidebarMinWidth))
  282.                                         newX = self.screenWidth - (self.isExpanded ? self.sidebarWidth : self.sidebarMinWidth);
  283.                                     if (newY > self.screenHeight - 100)
  284.                                         newY = self.screenHeight - 100;
  285.                                     
  286.                                     // 设置新位置
  287.                                     self.setPos(newX, newY);
  288.                                     
  289.                                     // 更新上次触摸位置
  290.                                     self.lastX = event.getRawX();
  291.                                     self.lastY = event.getRawY();
  292.                                 }
  293.                                 break;
  294.                             case MotionEvent.ACTION_UP:
  295.                                 self.dragging = false;
  296.                                 break;
  297.                         }
  298.                         return true;
  299.                     } catch (touchError) {
  300.                         // 静默处理触摸事件错误,避免崩溃
  301.                         return false;
  302.                     }
  303.                 }
  304.             }));
  305.         } else {
  306.             printl("⚠️ 无法设置拖拽事件,缺少必要组件");
  307.         }
  308.     } catch (touchSetupError) {
  309.         printl("❌ 设置拖拽事件失败: " + touchSetupError);
  310.     }
  311.    
  312.     // 展开/收起按钮点击事件
  313.     try {
  314.         if (this.toggleButton && this.toggleButton.setOnClickListener) {
  315.             this.toggleButton.setOnClickListener(function() {
  316.                 try {
  317.                     self.toggleExpand();
  318.                 } catch (toggleError) {
  319.                     printl("❌ 执行展开/收起操作失败: " + toggleError);
  320.                 }
  321.             });
  322.         }
  323.     } catch (toggleSetupError) {
  324.         printl("❌ 设置展开/收起事件失败: " + toggleSetupError);
  325.     }
  326.    
  327.     // 关闭按钮点击事件
  328.     try {
  329.         if (this.closeButton && this.closeButton.setOnClickListener) {
  330.             this.closeButton.setOnClickListener(function() {
  331.                 try {
  332.                     self.close();
  333.                 } catch (closeError) {
  334.                     printl("❌ 执行关闭操作失败: " + closeError);
  335.                 }
  336.             });
  337.         }
  338.     } catch (closeSetupError) {
  339.         printl("❌ 设置关闭事件失败: " + closeSetupError);
  340.     }
  341. };

  342. // 获取当前时间用于日志
  343. 侧栏日志.prototype.getCurrentTime = function() {
  344.     var now = new Date();
  345.     var hours = now.getHours().toString().padStart(2, '0');
  346.     var minutes = now.getMinutes().toString().padStart(2, '0');
  347.     var seconds = now.getSeconds().toString().padStart(2, '0');
  348.     return hours + ':' + minutes + ':' + seconds;
  349. };

  350. // 切换展开/收起状态
  351. 侧栏日志.prototype.toggleExpand = function() {
  352.     try {
  353.         var self = this;
  354.         
  355.         // 记录当前状态变更(使用printl避免递归)
  356.         printl("[" + self.getCurrentTime() + "] " + (self.isExpanded ? "&#128317; 侧栏正在收起" : "&#128316; 侧栏正在展开"));
  357.         // 定义要设置的目标宽度 - 修复逻辑:当前展开时应该设置为收起宽度,当前收起时应该设置为展开宽度
  358.         var targetWidth = this.isExpanded ? this.sidebarMinWidth : this.sidebarWidth;
  359.         
  360.         // 切换展开状态标志
  361.         this.isExpanded = !this.isExpanded;
  362.         
  363.         // 确保在主线程中执行UI操作
  364.         var uiOperation = function() {
  365.             self.performToggleExpand(targetWidth);
  366.         };
  367.         
  368.         // 尝试多种UI线程调度方案
  369.         var threadScheduled = false;
  370.         
  371.         // 方案1: 使用context.runOnUiThread
  372.         try {
  373.             if (context && context.runOnUiThread) {
  374.                 // 使用ES5兼容的方式创建Runnable对象
  375.                 var runnable = {
  376.                     run: function() {
  377.                         try {
  378.                             uiOperation();
  379.                         } catch (e) {
  380.                             printl("❌ UI线程执行失败: " + e);
  381.                         }
  382.                     }
  383.                 };
  384.                 context.runOnUiThread(runnable);
  385.                 threadScheduled = true;
  386.                 printl("✅ 使用context.runOnUiThread调度UI线程");
  387.             }
  388.         } catch (e) {
  389.             printl("❌ 方案1: context.runOnUiThread失败: " + e);
  390.         }
  391.         
  392.         // 方案2: 使用View.post (如果有任何View对象可用)
  393.         if (!threadScheduled) {
  394.             try {
  395.                 var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
  396.                 if (viewToUse && viewToUse.post) {
  397.                     viewToUse.post(function() {
  398.                         try {
  399.                             uiOperation();
  400.                         } catch (e) {
  401.                             printl("❌ View.post执行失败: " + e);
  402.                         }
  403.                     });
  404.                     threadScheduled = true;
  405.                     printl("✅ 使用View.post调度UI线程");
  406.                 }
  407.             } catch (e) {
  408.                 printl("❌ 方案2: View.post失败: " + e);
  409.             }
  410.         }
  411.         
  412.         // 方案3: 尝试使用Handler (如果可用)
  413.         if (!threadScheduled) {
  414.             try {
  415.                 if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
  416.                     var handler = new Handler(Looper.getMainLooper());
  417.                     handler.post(function() {
  418.                         try {
  419.                             uiOperation();
  420.                         } catch (e) {
  421.                             printl("❌ Handler执行失败: " + e);
  422.                         }
  423.                     });
  424.                     threadScheduled = true;
  425.                     printl("✅ 使用Handler调度UI线程");
  426.                 }
  427.             } catch (e) {
  428.                 printl("❌ 方案3: Handler失败: " + e);
  429.             }
  430.         }
  431.         
  432.         // 方案4: 直接执行作为最后备选 (可能会失败但提供降级方案)
  433.         if (!threadScheduled) {
  434.             printl("⚠️ 所有线程调度方案失败,尝试直接执行UI操作");
  435.             try {
  436.                 uiOperation();
  437.             } catch (directError) {
  438.                 printl("❌ 直接执行UI操作失败: " + directError);
  439.             }
  440.         }
  441.     } catch (e) {
  442.         printl("❌ 切换展开状态失败: " + e);
  443.     }
  444. };
  445. // 执行UI操作的核心方法(应在主线程中调用)
  446. 侧栏日志.prototype.performToggleExpand = function(targetWidth) {
  447.     try {
  448.         var self = this;
  449.         
  450.         // 切换UI元素可见性
  451.         if (!this.isExpanded) {
  452.             // 收起状态
  453.             if (this.titleText && typeof this.titleText.setVisibility === 'function') {
  454.                 try {
  455.                     this.titleText.setVisibility(View.GONE);
  456.                 } catch (e) {
  457.                     printl("❌ 设置titleText可见性失败: " + e);
  458.                 }
  459.             }
  460.             if (this.logContainer && typeof this.logContainer.setVisibility === 'function') {
  461.                 try {
  462.                     this.logContainer.setVisibility(View.GONE);
  463.                 } catch (e) {
  464.                     printl("❌ 设置logContainer可见性失败: " + e);
  465.                 }
  466.             }
  467.             if (this.closeButton && typeof this.closeButton.setVisibility === 'function') {
  468.                 try {
  469.                     this.closeButton.setVisibility(View.GONE); // 收起时隐藏关闭按钮
  470.                 } catch (e) {
  471.                     printl("❌ 设置closeButton可见性失败: " + e);
  472.                 }
  473.             }
  474.         } else {
  475.             // 展开状态
  476.             if (this.titleText && typeof this.titleText.setVisibility === 'function') {
  477.                 try {
  478.                     this.titleText.setVisibility(View.VISIBLE);
  479.                 } catch (e) {
  480.                     printl("❌ 设置titleText可见性失败: " + e);
  481.                 }
  482.             }
  483.             if (this.logContainer && typeof this.logContainer.setVisibility === 'function') {
  484.                 try {
  485.                     this.logContainer.setVisibility(View.VISIBLE);
  486.                 } catch (e) {
  487.                     printl("❌ 设置logContainer可见性失败: " + e);
  488.                 }
  489.             }
  490.             if (this.closeButton && typeof this.closeButton.setVisibility === 'function') {
  491.                 try {
  492.                     this.closeButton.setVisibility(View.VISIBLE); // 展开时显示关闭按钮
  493.                 } catch (e) {
  494.                     printl("❌ 设置closeButton可见性失败: " + e);
  495.                 }
  496.             }
  497.         }
  498.         
  499.         // 尝试多种方法来设置宽度,增加更多的备选方案
  500.         var widthSetSuccessfully = false;
  501.         var errorMessages = [];
  502.         
  503.         // 获取屏幕密度
  504.         var getDensity = function() {
  505.             try {
  506.                 if (context && context.getResources && context.getResources().getDisplayMetrics) {
  507.                     return context.getResources().getDisplayMetrics().density;
  508.                 }
  509.             } catch (e) {
  510.                 printl("⚠️ 获取屏幕密度失败: " + e);
  511.             }
  512.             return 3; // 默认密度
  513.         };
  514.         
  515.         // 方法1: 尝试通过FloatUI对象的可能方法
  516.         try {
  517.             if (this.ui && typeof this.ui.setLayoutWidth === 'function') {
  518.                 this.ui.setLayoutWidth(targetWidth);
  519.                 widthSetSuccessfully = true;
  520.                 printl("方法1: 使用setLayoutWidth设置宽度成功");
  521.             }
  522.         } catch (e) {
  523.             errorMessages.push("方法1: " + (e.message || String(e)));
  524.         }
  525.         
  526.         // 方法2: 尝试通过LayoutParams设置宽度
  527.         if (!widthSetSuccessfully) {
  528.             try {
  529.                 if (this.mainContainer && typeof this.mainContainer.getLayoutParams === 'function' &&
  530.                     typeof this.mainContainer.setLayoutParams === 'function') {
  531.                     var params = this.mainContainer.getLayoutParams();
  532.                     if (params) {
  533.                         // 尝试将dp转换为像素
  534.                         var pixelWidth = Math.round(targetWidth * getDensity());
  535.                         
  536.                         // 安全地设置宽度
  537.                         try {
  538.                             params.width = pixelWidth;
  539.                             this.mainContainer.setLayoutParams(params);
  540.                             widthSetSuccessfully = true;
  541.                             printl("方法2: 使用LayoutParams设置宽度成功");
  542.                         } catch (setParamsError) {
  543.                             errorMessages.push("方法2: " + (setParamsError.message || String(setParamsError)));
  544.                         }
  545.                     }
  546.                 }
  547.             } catch (e) {
  548.                 errorMessages.push("方法2: " + (e.message || String(e)));
  549.             }
  550.         }
  551.         
  552.         // 方法3: 尝试直接设置视图宽度
  553.         if (!widthSetSuccessfully) {
  554.             try {
  555.                 if (this.mainContainer && typeof this.mainContainer.setWidth === 'function') {
  556.                     // 使用已经计算好的像素宽度
  557.                     var pixelWidth = Math.round(targetWidth * getDensity());
  558.                     this.mainContainer.setWidth(pixelWidth);
  559.                     widthSetSuccessfully = true;
  560.                     printl("方法3: 使用setWidth设置宽度成功");
  561.                 }
  562.             } catch (e) {
  563.                 errorMessages.push("方法3: " + (e.message || String(e)));
  564.             }
  565.         }
  566.         
  567.         // 方法4: 尝试修改XML布局参数
  568.         if (!widthSetSuccessfully) {
  569.             try {
  570.                 if (this.ui && typeof this.ui.setLayoutParams === 'function') {
  571.                     // 尝试获取并修改FloatUI的布局参数
  572.                     var floatParams = (typeof this.ui.getLayoutParams === 'function') ? this.ui.getLayoutParams() : null;
  573.                     if (floatParams) {
  574.                         floatParams.width = Math.round(targetWidth * getDensity());
  575.                         this.ui.setLayoutParams(floatParams);
  576.                         widthSetSuccessfully = true;
  577.                         printl("方法4: 使用FloatUI.setLayoutParams设置宽度成功");
  578.                     }
  579.                 }
  580.             } catch (e) {
  581.                 errorMessages.push("方法4: " + (e.message || String(e)));
  582.             }
  583.         }
  584.         
  585.         // 方法5: 尝试使用layout方法直接设置位置和大小
  586.         if (!widthSetSuccessfully) {
  587.             try {
  588.                 if (this.mainContainer && typeof this.mainContainer.layout === 'function') {
  589.                     var left = 0;
  590.                     var top = 0;
  591.                     try {
  592.                         left = this.mainContainer.getLeft();
  593.                         top = this.mainContainer.getTop();
  594.                     } catch (positionError) {
  595.                         // 使用默认位置
  596.                     }
  597.                     var pixelWidth = Math.round(targetWidth * getDensity());
  598.                     var height = 0;
  599.                     try {
  600.                         height = this.mainContainer.getHeight();
  601.                     } catch (heightError) {
  602.                         height = 100; // 默认高度
  603.                     }
  604.                     this.mainContainer.layout(left, top, left + pixelWidth, top + height);
  605.                     widthSetSuccessfully = true;
  606.                     printl("方法5: 使用layout方法设置宽度成功");
  607.                 }
  608.             } catch (e) {
  609.                 errorMessages.push("方法5: " + (e.message || String(e)));
  610.             }
  611.         }
  612.         
  613.         // 尝试UI刷新方法
  614.         if (widthSetSuccessfully) {
  615.             try {
  616.                 if (this.ui && typeof this.ui.updateLayout === 'function') {
  617.                     this.ui.updateLayout();
  618.                     printl("UI布局已更新");
  619.                 } else if (this.mainContainer && typeof this.mainContainer.requestLayout === 'function') {
  620.                     this.mainContainer.requestLayout();
  621.                     printl("请求重新布局");
  622.                 } else if (this.mainContainer && typeof this.mainContainer.invalidate === 'function') {
  623.                     this.mainContainer.invalidate();
  624.                     printl("视图已刷新");
  625.                 }
  626.             } catch (e) {
  627.                 printl("刷新布局失败: " + e);
  628.             }
  629.         }
  630.         
  631.         // 设置按钮文本
  632.         if (this.toggleButton && typeof this.toggleButton.setText === 'function') {
  633.             try {
  634.                 this.toggleButton.setText("≡");
  635.             } catch (e) {
  636.                 printl("❌ 设置按钮文本失败: " + e);
  637.             }
  638.         }
  639.         
  640.         // 延迟100ms后记录状态更新,确保UI已更新
  641.         setTimeout(function() {
  642.             try {
  643.                 if (widthSetSuccessfully) {
  644.                     printl("✅ " + (self.isExpanded ? "侧栏已展开" : "侧栏已收起"));
  645.                 } else {
  646.                     // 只记录第一个错误信息,避免日志过多
  647.                     var mainError = errorMessages.length > 0 ? errorMessages[0] : "未知错误";
  648.                     printl(mainError);
  649.                     printl("⚠️ 侧栏" + (self.isExpanded ? "展开" : "收起") + "但宽度调整失败");
  650.                 }
  651.             } catch (e) {
  652.                 // 静默处理日志错误
  653.             }
  654.         }, 100);
  655.         
  656.         return widthSetSuccessfully;
  657.     } catch (e) {
  658.         printl("❌ 执行切换展开/收起操作失败: " + e);
  659.         return false;
  660.     }
  661. };

  662. // 添加日志
  663. 侧栏日志.prototype.log = function(message, color) {
  664.     try {
  665.         // 生成时间戳
  666.         var now = new Date();
  667.         var timeStr = now.getHours().toString().padStart(2, '0') + ":" +
  668.                       now.getMinutes().toString().padStart(2, '0') + ":" +
  669.                       now.getSeconds().toString().padStart(2, '0');
  670.         
  671.         // 格式化日志条目
  672.         var logEntry = "[" + timeStr + "] " + message;
  673.         
  674.         // 添加到日志数组
  675.         this.logs.push({text: logEntry, color: color || "#00FF00"});
  676.         
  677.         // 限制日志数量
  678.         if (this.logs.length > this.maxLogs) {
  679.             this.logs.shift(); // 移除最早的日志
  680.         }
  681.         
  682.         // 更新显示
  683.         this.updateLogDisplay();
  684.         
  685.         // 同时打印到控制台
  686.         printl(logEntry);
  687.     } catch (e) {
  688.         printl("❌ 添加日志失败: " + e);
  689.     }
  690. };

  691. // 更新日志显示
  692. 侧栏日志.prototype.updateLogDisplay = function() {
  693.     try {
  694.         var self = this;
  695.         var uiOperation = function() {
  696.             self.performUpdateLogDisplay();
  697.         };
  698.         
  699.         // 尝试多种UI线程调度方案
  700.         var threadScheduled = false;
  701.         
  702.         // 方案1: 使用context.runOnUiThread
  703.         try {
  704.             if (context && context.runOnUiThread) {
  705.                 var runnable = {
  706.                     run: function() {
  707.                         try {
  708.                             uiOperation();
  709.                         } catch (e) {
  710.                             printl("❌ UI线程执行日志更新失败: " + e);
  711.                         }
  712.                     }
  713.                 };
  714.                 context.runOnUiThread(runnable);
  715.                 threadScheduled = true;
  716.             }
  717.         } catch (e) {
  718.             printl("❌ 方案1: context.runOnUiThread调度日志更新失败: " + e);
  719.         }
  720.         
  721.         // 方案2: 使用View.post
  722.         if (!threadScheduled) {
  723.             try {
  724.                 var viewToUse = self.logText || self.logContainer || self.mainContainer;
  725.                 if (viewToUse && viewToUse.post) {
  726.                     viewToUse.post(function() {
  727.                         try {
  728.                             uiOperation();
  729.                         } catch (e) {
  730.                             printl("❌ View.post执行日志更新失败: " + e);
  731.                         }
  732.                     });
  733.                     threadScheduled = true;
  734.                 }
  735.             } catch (e) {
  736.                 printl("❌ 方案2: View.post调度日志更新失败: " + e);
  737.             }
  738.         }
  739.         
  740.         // 方案3: 尝试使用Handler
  741.         if (!threadScheduled) {
  742.             try {
  743.                 if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
  744.                     var handler = new Handler(Looper.getMainLooper());
  745.                     handler.post(function() {
  746.                         try {
  747.                             uiOperation();
  748.                         } catch (e) {
  749.                             printl("❌ Handler执行日志更新失败: " + e);
  750.                         }
  751.                     });
  752.                     threadScheduled = true;
  753.                 }
  754.             } catch (e) {
  755.                 printl("❌ 方案3: Handler调度日志更新失败: " + e);
  756.             }
  757.         }
  758.         
  759.         // 方案4: 直接执行作为最后备选
  760.         if (!threadScheduled) {
  761.             try {
  762.                 uiOperation();
  763.             } catch (directError) {
  764.                 printl("❌ 直接执行日志更新失败: " + directError);
  765.             }
  766.         }
  767.     } catch (e) {
  768.         printl("❌ 更新日志显示失败: " + e);
  769.     }
  770. };

  771. // 执行日志显示更新的核心方法(应在主线程中调用)
  772. 侧栏日志.prototype.performUpdateLogDisplay = function() {
  773.     try {
  774.         // 检查logText是否存在
  775.         if (!this.logText || typeof this.logText.setText !== 'function') {
  776.             printl("⚠️ 日志显示组件不可用");
  777.             return;
  778.         }
  779.         
  780.         // 构建日志文本
  781.         var logText = "";
  782.         var useHtml = false;
  783.         
  784.         // 尝试HTML格式
  785.         try {
  786.             if (typeof android.text.Html !== 'undefined' && typeof android.text.Html.fromHtml === 'function') {
  787.                 var htmlText = "";
  788.                 for (var i = 0; i < this.logs.length; i++) {
  789.                     var log = this.logs[i];
  790.                     var color = log.color || "#00FF00";
  791.                     htmlText += "<font color=\"" + color + "\">" + log.text + "</font><br/>";
  792.                 }
  793.                
  794.                 try {
  795.                     var spanned = android.text.Html.fromHtml(htmlText);
  796.                     this.logText.setText(spanned);
  797.                     useHtml = true;
  798.                     printl("✅ 日志使用HTML格式显示");
  799.                 } catch (htmlError) {
  800.                     printl("⚠️ HTML格式化失败,回退到纯文本: " + htmlError);
  801.                 }
  802.             }
  803.         } catch (e) {
  804.             printl("⚠️ HTML支持不可用: " + e);
  805.         }
  806.         
  807.         // 如果HTML格式失败,使用纯文本格式
  808.         if (!useHtml) {
  809.             for (var i = 0; i < this.logs.length; i++) {
  810.                 logText += this.logs[i].text + "\n";
  811.             }
  812.             
  813.             try {
  814.                 this.logText.setText(logText);
  815.                 printl("✅ 日志使用纯文本格式显示");
  816.             } catch (textError) {
  817.                 printl("❌ 设置日志文本失败: " + textError);
  818.             }
  819.         }
  820.         
  821.         // 尝试滚动到底部
  822.         var self = this;
  823.         try {
  824.             if (this.logContainer && typeof this.logContainer.post === 'function') {
  825.                 this.logContainer.post(function() {
  826.                     try {
  827.                         if (self.logContainer && typeof self.logContainer.fullScroll === 'function') {
  828.                             self.logContainer.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
  829.                         }
  830.                     } catch (scrollError) {
  831.                         // 静默处理滚动错误
  832.                     }
  833.                 });
  834.             } else if (this.logContainer && typeof this.logContainer.fullScroll === 'function') {
  835.                 this.logContainer.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
  836.             }
  837.         } catch (e) {
  838.             // 静默处理滚动错误
  839.         }
  840.     } catch (e) {
  841.         printl("❌ 执行日志显示更新失败: " + e);
  842.     }
  843. };

  844. // 设置悬浮窗位置
  845. 侧栏日志.prototype.setPos = function(x, y) {
  846.     try {
  847.         var self = this;
  848.         
  849.         // 参数验证
  850.         if (typeof x !== 'number' || typeof y !== 'number') {
  851.             printl("❌ setPos参数错误: x和y必须是数字");
  852.             return false;
  853.         }
  854.         
  855.         // 边界检查
  856.         var currentWidth = this.isExpanded ? this.sidebarWidth : this.sidebarMinWidth;
  857.         try {
  858.             if (context && context.getResources && context.getResources().getDisplayMetrics) {
  859.                 var density = context.getResources().getDisplayMetrics().density;
  860.                 currentWidth *= density;
  861.             }
  862.         } catch (e) {
  863.             currentWidth *= 3; // 使用默认密度倍数
  864.         }
  865.         
  866.         if (x < 0) x = 0;
  867.         if (y < 0) y = 0;
  868.         if (x > this.screenWidth - currentWidth) x = this.screenWidth - currentWidth;
  869.         if (y > this.screenHeight - 100) y = this.screenHeight - 100;
  870.         
  871.         // 使用printl避免递归调用
  872.         printl("&#128260; 设置悬浮窗位置: x=" + x + ", y=" + y);
  873.         
  874.         // 定义UI操作函数
  875.         var uiOperation = function() {
  876.             self.performSetPos(x, y);
  877.         };
  878.         
  879.         // 尝试多种UI线程调度方案
  880.         var threadScheduled = false;
  881.         
  882.         // 方案1: 使用context.runOnUiThread
  883.         try {
  884.             if (context && context.runOnUiThread) {
  885.                 var runnable = {
  886.                     run: function() {
  887.                         try {
  888.                             uiOperation();
  889.                         } catch (e) {
  890.                             printl("❌ UI线程执行位置设置失败: " + e);
  891.                         }
  892.                     }
  893.                 };
  894.                 context.runOnUiThread(runnable);
  895.                 threadScheduled = true;
  896.                 printl("✅ 使用context.runOnUiThread调度位置设置");
  897.             }
  898.         } catch (e) {
  899.             printl("❌ 方案1: context.runOnUiThread调度位置设置失败: " + e);
  900.         }
  901.         
  902.         // 方案2: 使用View.post
  903.         if (!threadScheduled) {
  904.             try {
  905.                 var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
  906.                 if (viewToUse && typeof viewToUse.post === 'function') {
  907.                     viewToUse.post(function() {
  908.                         try {
  909.                             uiOperation();
  910.                         } catch (e) {
  911.                             printl("❌ View.post执行位置设置失败: " + e);
  912.                         }
  913.                     });
  914.                     threadScheduled = true;
  915.                     printl("✅ 使用View.post调度位置设置");
  916.                 }
  917.             } catch (e) {
  918.                 printl("❌ 方案2: View.post调度位置设置失败: " + e);
  919.             }
  920.         }
  921.         
  922.         // 方案3: 尝试使用Handler
  923.         if (!threadScheduled) {
  924.             try {
  925.                 if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
  926.                     var handler = new Handler(Looper.getMainLooper());
  927.                     handler.post(function() {
  928.                         try {
  929.                             uiOperation();
  930.                         } catch (e) {
  931.                             printl("❌ Handler执行位置设置失败: " + e);
  932.                         }
  933.                     });
  934.                     threadScheduled = true;
  935.                     printl("✅ 使用Handler调度位置设置");
  936.                 }
  937.             } catch (e) {
  938.                 printl("❌ 方案3: Handler调度位置设置失败: " + e);
  939.             }
  940.         }
  941.         
  942.         // 方案4: 直接执行作为最后备选
  943.         if (!threadScheduled) {
  944.             printl("⚠️ 所有线程调度方案失败,尝试直接执行位置设置");
  945.             try {
  946.                 uiOperation();
  947.             } catch (directError) {
  948.                 printl("❌ 直接执行位置设置失败: " + directError);
  949.             }
  950.         }
  951.         
  952.         return true;
  953.     } catch (e) {
  954.         printl("❌ 设置位置失败: " + e);
  955.         return false;
  956.     }
  957. };

  958. // 执行设置位置的核心方法(应在主线程中调用)
  959. 侧栏日志.prototype.performSetPos = function(x, y) {
  960.     try {
  961.         var posSetSuccess = false;
  962.         
  963.         // 方案1: 尝试使用floatUI的setPos方法
  964.         try {
  965.             if (this.ui && this.ui.setPos) {
  966.                 this.ui.setPos(x, y);
  967.                 posSetSuccess = true;
  968.                 printl("✅ 方案1: 使用floatUI.setPos设置位置成功");
  969.             }
  970.         } catch (e) {
  971.             printl("❌ 方案1: floatUI.setPos失败: " + e);
  972.         }
  973.         
  974.         // 方案2: 尝试使用floatUI的setPosition方法
  975.         if (!posSetSuccess) {
  976.             try {
  977.                 if (this.ui && this.ui.setPosition) {
  978.                     this.ui.setPosition(x, y);
  979.                     posSetSuccess = true;
  980.                     printl("✅ 方案2: 使用floatUI.setPosition设置位置成功");
  981.                 }
  982.             } catch (e) {
  983.                 printl("❌ 方案2: floatUI.setPosition失败: " + e);
  984.             }
  985.         }
  986.         
  987.         // 方案3: 尝试使用setX和setY方法(如果可用)
  988.         if (!posSetSuccess) {
  989.             try {
  990.                 if (this.ui && typeof this.ui.setX === 'function' && typeof this.ui.setY === 'function') {
  991.                     this.ui.setX(x);
  992.                     this.ui.setY(y);
  993.                     posSetSuccess = true;
  994.                     printl("✅ 方案3: 使用ui.setX/setY设置位置成功");
  995.                 }
  996.             } catch (e) {
  997.                 printl("❌ 方案3: ui.setX/setY失败: " + e);
  998.             }
  999.         }
  1000.         
  1001.         // 方案4: 尝试通过mainContainer设置位置
  1002.         if (!posSetSuccess) {
  1003.             try {
  1004.                 if (this.mainContainer && typeof this.mainContainer.setX === 'function' && typeof this.mainContainer.setY === 'function') {
  1005.                     this.mainContainer.setX(x);
  1006.                     this.mainContainer.setY(y);
  1007.                     posSetSuccess = true;
  1008.                     printl("✅ 方案4: 使用mainContainer.setX/setY设置位置成功");
  1009.                 }
  1010.             } catch (e) {
  1011.                 printl("❌ 方案4: mainContainer.setX/setY失败: " + e);
  1012.             }
  1013.         }
  1014.         
  1015.         // 方案5: 尝试通过直接访问mainContainer设置位置
  1016.         if (!posSetSuccess) {
  1017.             try {
  1018.                 if (this.mainContainer && typeof this.mainContainer.layout === 'function' && typeof this.mainContainer.getWidth === 'function' && typeof this.mainContainer.getHeight === 'function') {
  1019.                     this.mainContainer.layout(x, y, x + this.mainContainer.getWidth(), y + this.mainContainer.getHeight());
  1020.                     posSetSuccess = true;
  1021.                     printl("✅ 方案5: 使用layout方法设置位置成功");
  1022.                 }
  1023.             } catch (e) {
  1024.                 printl("❌ 方案5: layout方法失败: " + e);
  1025.             }
  1026.         }
  1027.         
  1028.         // 刷新UI确保位置更新生效
  1029.         if (posSetSuccess) {
  1030.             try {
  1031.                 // 尝试多种刷新方法
  1032.                 if (this.mainContainer) {
  1033.                     if (typeof this.mainContainer.invalidate === 'function') {
  1034.                         this.mainContainer.invalidate();
  1035.                     }
  1036.                     if (typeof this.mainContainer.requestLayout === 'function') {
  1037.                         this.mainContainer.requestLayout();
  1038.                     }
  1039.                 }
  1040.                 printl("✅ 位置设置刷新完成");
  1041.             } catch (refreshError) {
  1042.                 printl("⚠️ 刷新位置时出错: " + refreshError);
  1043.             }
  1044.         } else {
  1045.             printl("⚠️ 位置设置完成但可能未生效");
  1046.         }
  1047.         
  1048.         return posSetSuccess;
  1049.     } catch (e) {
  1050.         printl("❌ 执行位置设置失败: " + e);
  1051.         return false;
  1052.     }
  1053. };

  1054. // 清空日志
  1055. 侧栏日志.prototype.clearLogs = function() {
  1056.     try {
  1057.         // 清空日志数组
  1058.         this.logs = [];
  1059.         
  1060.         // 清空日志显示
  1061.         if (this.logText && this.logText.setText) {
  1062.             try {
  1063.                 this.logText.setText("");
  1064.             } catch (setTextError) {
  1065.                 printl("⚠️ 清空日志显示失败: " + setTextError);
  1066.             }
  1067.         }
  1068.         
  1069.         // 记录清空操作
  1070.         this.log("&#128465;️ 日志已清空", "#FF0000");
  1071.         return true;
  1072.     } catch (e) {
  1073.         printl("❌ 清空日志失败: " + e);
  1074.         return false;
  1075.     }
  1076. };

  1077. // 关闭悬浮窗
  1078. 侧栏日志.prototype.close = function() {
  1079.     try {
  1080.         var self = this;
  1081.         
  1082.         // 使用printl避免递归调用
  1083.         printl("&#128260; 正在关闭侧栏日志悬浮窗...");
  1084.         
  1085.         // 定义UI操作函数
  1086.         var uiOperation = function() {
  1087.             self.performClose();
  1088.         };
  1089.         
  1090.         // 尝试多种UI线程调度方案
  1091.         var threadScheduled = false;
  1092.         
  1093.         // 方案1: 使用context.runOnUiThread
  1094.         try {
  1095.             if (context && context.runOnUiThread) {
  1096.                 var runnable = {
  1097.                     run: function() {
  1098.                         try {
  1099.                             uiOperation();
  1100.                         } catch (e) {
  1101.                             printl("❌ UI线程执行关闭操作失败: " + e);
  1102.                         }
  1103.                     }
  1104.                 };
  1105.                 context.runOnUiThread(runnable);
  1106.                 threadScheduled = true;
  1107.                 printl("✅ 使用context.runOnUiThread调度关闭操作");
  1108.             }
  1109.         } catch (e) {
  1110.             printl("❌ 方案1: context.runOnUiThread调度关闭操作失败: " + e);
  1111.         }
  1112.         
  1113.         // 方案2: 使用View.post
  1114.         if (!threadScheduled) {
  1115.             try {
  1116.                 var viewToUse = self.mainContainer || self.titleBar || self.toggleButton;
  1117.                 if (viewToUse && typeof viewToUse.post === 'function') {
  1118.                     viewToUse.post(function() {
  1119.                         try {
  1120.                             uiOperation();
  1121.                         } catch (e) {
  1122.                             printl("❌ View.post执行关闭操作失败: " + e);
  1123.                         }
  1124.                     });
  1125.                     threadScheduled = true;
  1126.                     printl("✅ 使用View.post调度关闭操作");
  1127.                 }
  1128.             } catch (e) {
  1129.                 printl("❌ 方案2: View.post调度关闭操作失败: " + e);
  1130.             }
  1131.         }
  1132.         
  1133.         // 方案3: 尝试使用Handler
  1134.         if (!threadScheduled) {
  1135.             try {
  1136.                 if (typeof Handler !== 'undefined' && typeof Looper !== 'undefined' && Looper.getMainLooper) {
  1137.                     var handler = new Handler(Looper.getMainLooper());
  1138.                     handler.post(function() {
  1139.                         try {
  1140.                             uiOperation();
  1141.                         } catch (e) {
  1142.                             printl("❌ Handler执行关闭操作失败: " + e);
  1143.                         }
  1144.                     });
  1145.                     threadScheduled = true;
  1146.                     printl("✅ 使用Handler调度关闭操作");
  1147.                 }
  1148.             } catch (e) {
  1149.                 printl("❌ 方案3: Handler调度关闭操作失败: " + e);
  1150.             }
  1151.         }
  1152.         
  1153.         // 方案4: 直接执行作为最后备选
  1154.         if (!threadScheduled) {
  1155.             printl("⚠️ 所有线程调度方案失败,尝试直接执行关闭操作");
  1156.             try {
  1157.                 uiOperation();
  1158.             } catch (directError) {
  1159.                 printl("❌ 直接执行关闭操作失败: " + directError);
  1160.             }
  1161.         }
  1162.     } catch (e) {
  1163.         printl("❌ 关闭侧栏日志悬浮窗失败: " + e);
  1164.     }
  1165. };

  1166. // 执行关闭操作的核心方法(应在主线程中调用)
  1167. 侧栏日志.prototype.performClose = function() {
  1168.     try {
  1169.         printl("&#128260; 执行悬浮窗关闭操作...");
  1170.         
  1171.         // 尝试多种关闭方案
  1172.         var closeSuccess = false;
  1173.         
  1174.         // 方案1: 尝试使用close方法
  1175.         try {
  1176.             if (this.ui && typeof this.ui.close === 'function') {
  1177.                 this.ui.close();
  1178.                 closeSuccess = true;
  1179.                 printl("✅ 方案1: 使用ui.close()成功关闭");
  1180.             }
  1181.         } catch (e) {
  1182.             printl("❌ 方案1: 使用ui.close()关闭失败: " + e);
  1183.         }
  1184.         
  1185.         // 方案2: 尝试使用destroy方法
  1186.         if (!closeSuccess) {
  1187.             try {
  1188.                 if (this.ui && typeof this.ui.destroy === 'function') {
  1189.                     this.ui.destroy();
  1190.                     closeSuccess = true;
  1191.                     printl("✅ 方案2: 使用ui.destroy()成功关闭");
  1192.                 }
  1193.             } catch (e) {
  1194.                 printl("❌ 方案2: 使用ui.destroy()关闭失败: " + e);
  1195.             }
  1196.         }
  1197.         
  1198.         // 方案3: 尝试从父容器移除
  1199.         if (!closeSuccess) {
  1200.             try {
  1201.                 if (this.mainContainer && typeof this.mainContainer.getParent === 'function') {
  1202.                     var parent = this.mainContainer.getParent();
  1203.                     if (parent && typeof parent.removeView === 'function') {
  1204.                         parent.removeView(this.mainContainer);
  1205.                         closeSuccess = true;
  1206.                         printl("✅ 方案3: 从父容器移除成功");
  1207.                     }
  1208.                 }
  1209.             } catch (e) {
  1210.                 printl("❌ 方案3: 从父容器移除失败: " + e);
  1211.             }
  1212.         }
  1213.         
  1214.         // 方案4: 尝试隐藏视图
  1215.         if (!closeSuccess) {
  1216.             try {
  1217.                 if (this.mainContainer && typeof this.mainContainer.setVisibility === 'function') {
  1218.                     this.mainContainer.setVisibility(View.GONE);
  1219.                     closeSuccess = true;
  1220.                     printl("✅ 方案4: 隐藏视图成功");
  1221.                 }
  1222.             } catch (e) {
  1223.                 printl("❌ 方案4: 隐藏视图失败: " + e);
  1224.             }
  1225.         }
  1226.         
  1227.         // 清理资源
  1228.         try {
  1229.             // 清除事件监听器
  1230.             if (this.titleBar && typeof this.titleBar.setOnTouchListener === 'function') {
  1231.                 this.titleBar.setOnTouchListener(null);
  1232.             }
  1233.             if (this.toggleButton && typeof this.toggleButton.setOnClickListener === 'function') {
  1234.                 this.toggleButton.setOnClickListener(null);
  1235.             }
  1236.             if (this.closeButton && typeof this.closeButton.setOnClickListener === 'function') {
  1237.                 this.closeButton.setOnClickListener(null);
  1238.             }
  1239.             
  1240.             // 清除引用,帮助垃圾回收
  1241.             this.ui = null;
  1242.             this.mainContainer = null;
  1243.             this.titleBar = null;
  1244.             this.toggleButton = null;
  1245.             this.closeButton = null;
  1246.             this.titleText = null;
  1247.             this.logContainer = null;
  1248.             this.logText = null;
  1249.             this.logs = null;
  1250.             
  1251.             printl("✅ 资源清理完成");
  1252.         } catch (cleanupError) {
  1253.             printl("⚠️ 资源清理时出错: " + cleanupError);
  1254.         }
  1255.         
  1256.         // 更新状态
  1257.         sidebarLogger = null;
  1258.         
  1259.         // 记录关闭结果
  1260.         if (closeSuccess) {
  1261.             printl("✅ 侧栏日志悬浮窗已成功关闭");
  1262.         } else {
  1263.             printl("⚠️ 侧栏日志悬浮窗尝试关闭,但可能未完全成功");
  1264.         }
  1265.         
  1266.         return closeSuccess;
  1267.     } catch (e) {
  1268.         printl("❌ 执行关闭操作失败: " + e);
  1269.         return false;
  1270.     }
  1271. };

  1272. // 创建并启动侧栏日志悬浮窗
  1273. var sidebarLogger = null;

  1274. // 版本信息
  1275. const SIDEBAR_LOGGER_VERSION = "1.2.0";

  1276. // 初始化悬浮窗
  1277. function initSidebarLogger(options) {
  1278.     try {
  1279.         // 防止重复初始化
  1280.         if (sidebarLogger) {
  1281.             printl("⚠️ 侧栏日志已经初始化,无需重复创建");
  1282.             return sidebarLogger;
  1283.         }
  1284.         
  1285.         // 合并默认选项和用户选项
  1286.         options = options || {};
  1287.         
  1288.         // 环境检查
  1289.         if (typeof floatUI === 'undefined') {
  1290.             printl("❌ 错误:未找到floatUI库,请确保在AIWROK环境中运行!");
  1291.             return null;
  1292.         }
  1293.         
  1294.         // 打印启动信息
  1295.         printl("====================================");
  1296.         printl("&#128260; 侧栏日志悬浮窗初始化中...");
  1297.         printl("&#128241; 版本: " + SIDEBAR_LOGGER_VERSION);
  1298.         printl("====================================");
  1299.         
  1300.         // 创建悬浮窗实例
  1301.         sidebarLogger = new 侧栏日志();
  1302.         
  1303.         // 创建悬浮窗
  1304.         if (sidebarLogger.create()) {
  1305.             printl("✅ 侧栏日志悬浮窗已创建成功!");
  1306.             
  1307.             // 添加欢迎日志
  1308.             sidebarLogger.log("&#127881; 欢迎使用侧栏日志工具", "#00FFFF");
  1309.             sidebarLogger.log("&#128241; 版本: " + SIDEBAR_LOGGER_VERSION, "#00FFFF");
  1310.             sidebarLogger.log("&#128161; 点击≡按钮展开/收起侧栏", "#FFFF00");
  1311.             sidebarLogger.log("&#128260; 拖动标题栏可移动悬浮窗", "#FFFF00");
  1312.             sidebarLogger.log("&#128465;️ 右上角关闭按钮可关闭悬浮窗", "#FFFF00");
  1313.             sidebarLogger.log("&#128161; 可使用sidebarLogger.log()添加自定义日志", "#00FF00");
  1314.             
  1315.             // 自动展开悬浮窗,让用户看到关闭按钮
  1316.             try {
  1317.                 setTimeout(function() {
  1318.                     if (sidebarLogger && typeof sidebarLogger.toggleExpand === 'function') {
  1319.                         sidebarLogger.toggleExpand();
  1320.                     }
  1321.                 }, 500);
  1322.             } catch (autoExpandError) {
  1323.                 printl("⚠️ 自动展开失败: " + autoExpandError);
  1324.             }
  1325.             
  1326.             return sidebarLogger;
  1327.         } else {
  1328.             printl("❌ 侧栏日志悬浮窗创建失败!");
  1329.             sidebarLogger = null;
  1330.             return null;
  1331.         }
  1332.     } catch (e) {
  1333.         printl("❌ 初始化侧栏日志失败: " + e);
  1334.         sidebarLogger = null;
  1335.         return null;
  1336.     }
  1337. }

  1338. // 安全获取侧栏日志实例
  1339. function getSidebarLogger() {
  1340.     return sidebarLogger;
  1341. }

  1342. // 安全地记录日志(即使悬浮窗未初始化也不会报错)
  1343. function safeLog(message, color) {
  1344.     if (sidebarLogger && typeof sidebarLogger.log === 'function') {
  1345.         try {
  1346.             sidebarLogger.log(message, color);
  1347.             return true;
  1348.         } catch (e) {
  1349.             printl("⚠️ 记录日志失败: " + e);
  1350.         }
  1351.     }
  1352.     // 降级到console.log
  1353.     printl(message || "");
  1354.     return false;
  1355. }

  1356. // 启动悬浮窗
  1357. try {
  1358.     // 延迟初始化,确保环境准备就绪
  1359.     setTimeout(function() {
  1360.         initSidebarLogger();
  1361.     }, 100);
  1362. } catch (startupError) {
  1363.     printl("❌ 启动悬浮窗失败: " + startupError);
  1364.     // 作为最后的备选,尝试直接初始化
  1365.     try {
  1366.         initSidebarLogger();
  1367.     } catch (finalError) {
  1368.         printl("❌ 直接初始化也失败: " + finalError);
  1369.     }
  1370. }
复制代码



untoAIWROK软件安卓工具箱悬浮窗next安卓toast吐司的各种方法应用实例
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关导读
群发软件AIWROK苹果系统实例演示1标签类[Label]方法
AIWROK苹果系统实例演示1标签类[Label]方法
信息发布软件AIWROK软件苹果UI按钮Button方法示例
AIWROK软件苹果UI按钮Button方法示例
信息发布软件AIWROK软件苹果TAB界面视图示例
AIWROK软件苹果TAB界面视图示例
信息发布软件AIWROK苹果系统自带view视图简洁UI界面示例
AIWROK苹果系统自带view视图简洁UI界面示例
信息发布软件汇集HID安卓输入文字的方法和复制粘贴示例
汇集HID安卓输入文字的方法和复制粘贴示例
信息发布软件AIWROK软件找字与OCR方法汇总示例
AIWROK软件找字与OCR方法汇总示例
信息发布软件AIWROK软件找图方法汇总示例
AIWROK软件找图方法汇总示例
信息发布软件AIWROK软件滑动方法集合示例
AIWROK软件滑动方法集合示例
信息发布软件AIWROK软件安卓AIWROK汇集软件点击
AIWROK软件安卓AIWROK汇集软件点击
信息发布软件苹果系统点击方法综合示例
苹果系统点击方法综合示例
信息发布软件AIWROK苹果系统找图方法完整示例集合
AIWROK苹果系统找图方法完整示例集合
信息发布软件苹果系统找图方法完整示例集合
苹果系统找图方法完整示例集合
信息发布软件苹果IOS系统找字OCR方法例子
苹果IOS系统找字OCR方法例子
信息发布软件AIWORK软件数组高级示例
AIWORK软件数组高级示例
信息发布软件AIWROK软件运算符封装库示例
AIWROK软件运算符封装库示例
信息发布软件AIWROK软件语法运行小示例
AIWROK软件语法运行小示例
信息发布软件AIWROK软件JS循环小示例
AIWROK软件JS循环小示例
信息发布软件AIWROK软件H5网页被主脚本获取值用法
AIWROK软件H5网页被主脚本获取值用法
信息发布软件AIWROK软件创建可暂停恢复的多线程任务
AIWROK软件创建可暂停恢复的多线程任务
信息发布软件AIWROK软件类型转换方法例子
AIWROK软件类型转换方法例子
信息发布软件AIWROK软件H5脚本执行与进度显示
AIWROK软件H5脚本执行与进度显示 .
信息发布软件AIWROK软件根据时间段执行异步任务支持多线程并行处理
AIWROK软件根据时间段执行异步任务支持多线程并行处理
信息发布软件H5自动开关执行脚本功能演示
H5自动开关执行脚本功能演示
信息发布软件AIWROK软件H5单选脚本运行示例
AIWROK软件H5单选脚本运行示例
信息发布软件H5任务脚本选择与执行中心
H5任务脚本选择与执行中心
信息发布软件H5里CheckBox控件演示
H5里CheckBox控件演示
信息发布软件AIWROK软件正则用法实际例子
AIWROK软件正则用法实际例子
信息发布软件AIWROK软件权限管理器实现
AIWROK软件权限管理器实现
信息发布软件AIWORK软件节点方法无碍示例子
AIWORK软件节点方法无碍示例子
信息发布软件JSON.stringify 和 JSON.parse 完整示例
JSON.stringify 和 JSON.parse 完整示例
信息发布软件AIWROK软件展示JavaScript各种语句标识符的用法
AIWROK软件展示JavaScript各种语句标识符的用法
信息发布软件JS巧妙地组合使用各种条件语句
JS巧妙地组合使用各种条件语句
信息发布软件AIWROK手机数据库MySQL数据库截图片批量上传操作脚本
AIWROK手机数据库MySQL数据库截图片批量上传操作脚本
信息发布软件HID中文输入智能打字功能
HID中文输入智能打字功能
信息发布软件AIWROK软件对象工具函数库例子
AIWROK软件对象工具函数库例子
信息发布软件AIWROK软件H5交互演示黄色主题
AIWROK软件H5交互演示黄色主题
信息发布软件H5单按钮执行脚本示例
H5单按钮执行脚本示例
信息发布软件苹果H5界面完整调用脚本示例
苹果H5界面完整调用脚本示例
信息发布软件AIWROK软件平台设备信息全面检测工具例子
AIWROK软件平台设备信息全面检测工具例子
信息发布软件AIWROK创建和放大日志窗口并展示动态内容
AIWROK创建和放大日志窗口并展示动态内容
信息发布软件AIWROK软件device相关方法获取设备信息例子
AIWROK软件device相关方法获取设备信息例子[/backcolor]
信息发布软件数据库MySQL实时内容随机调用
数据库MySQL实时内容随机调用
信息发布软件AIWROK软件分享一个特效苹果H5页面
AIWROK软件分享一个特效苹果H5页面
信息发布软件数据库MYQ业务流程心跳程序启动
数据库MYQ业务流程心跳程序启动
信息发布软件数据库MySQL功能支持创建表插入中文数据查询删除功能例子
数据库MySQL功能支持创建表插入中文数据查询删除功能例子
信息发布软件AIWROK软件Zip 高级操作复杂示例
AIWROK软件Zip 高级操作复杂示例
信息发布软件AIWROK软件txt_文件读写方法小结
AIWROK软件txt_文件读写方法小结
信息发布软件AIWROK软件file文件操作方法小结
AIWROK软件file文件操作方法小结
信息发布软件AIWORK软件配置读写H5演示配套脚本
AIWORK软件配置读写H5演示配套脚本
信息发布软件AIWROK配置读写功能演示示例
AIWROK配置读写功能演示示例
信息发布软件AIWROK截图缓存工具
AIWROK截图缓存工具
信息发布软件AIWROK线程许可证工具
AIWROK线程许可证工具
信息发布软件整理了AIWROK环境下常用的Date对象和sleep对象方法
整理了AIWROK环境下常用的Date对象和sleep对象方法
信息发布软件FastUI界面普通用法
FastUI界面普通用法
信息发布软件FastUI界面类[window]方法小结
FastUI界面类[window]方法小结 方法 1:close(关闭指定窗口)方法 2:closeAll(关闭所有窗口)方法 3:loadUI(加载 UI 界面)方法 4:onClose(监听窗口关闭事件)方法 5:onLoad(监听窗口加载事件)方法 6:setFull(设置窗口全屏)方法 7:setHeight(设置窗口高度)方法 8:setHidden(隐藏窗口)方法 9:setLeft(设置窗口 X 轴坐标)方法 10:setTop(设置窗口 Y 轴坐标)方法 11:setVisable(显示隐藏的窗口)方
信息发布软件AIWROK软件按钮监听UI界面与事件监听功能演示
AIWROK软件按钮监听UI界面与事件监听功能演示.
信息发布软件AWIROK软件多选[uiCheckBox]方法小结
AWIROK软件多选方法小结 方法一:findByID 加载多选控件方法二:getAllChecked 获取所有选中项方法三:getAllSelect 获取所有选项方法四:getChecked 获取某个选项是否选中方法五:setChecked 设置某个选项是否选中方法六:setCheckeds 设置多个选项是否选中方法七:setHeight 设置高度
信息发布软件AIWROK日志演示开启日志显示 → 放大 → 关闭代码
AIWROK日志演示开启日志显示 → 放大 → 关闭代码
信息发布软件&#127983;AIWROK数组方法高级应用案例
🏯AIWROK数组方法高级应用案例
信息发布软件AIWROK软件日志悬浮窗简化版自动切换位置
AIWROK软件日志悬浮窗简化版自动切换位置
信息发布软件AIWROK软件String实例演示
AIWROK软件String实例演示
信息发布软件AIWROK软件S内置String类[String]方法小结
AIWROK软件S内置String类[String]方法小结 方法 1:charAt[/backcolor]方法 2:charCodeAt[/backcolor]方法 3:indexOf[/backcolor]方法 4:lastIndexOf[/backcolor]方法 5:length[/backcolor]方法 6:match[/backcolor]方法 7:replace[/backcolor]方法 8:replaceAll[/backcolor]方法 9:split[/backcolor]方法 10:startsWith[/backcolor]方法 11:substr[/backcolor]方法 12:substring[/backcolor]方法 13:trim[/backcol
信息发布软件AIWROK软件完整的WebSocket客户端示例
这段代码是一个完整的WebSocket客户端示例,用于连接到指定的WebSocket服务器并处理各种事件。具体来说,代码的作用如下: 定义服务器地址:首先定义了一个服务器的IP地址和端口号 var ip = "154.37.221.104:8886";。 创建WebSocket对象:尝试创建一个新的WebSocket对象 var ws = new WebSocket();。注意,这里的 new ws() 应该是 new WebSocket()。 添加事件监听器:代码中尝试为WebSocket对象添加事件监听器,但这里有一个错误。
信息发布软件AIWROK软件苹果系统中实现四种基本滑动操作
AIWROK软件苹果系统中实现四种基本滑动操作
信息发布软件hid的滑动没有百分比坐标滑动吗
hid的滑动没有百分比坐标滑动吗

QQ|( 京ICP备09078825号 )

本网站信息发布软件,是可以发布论坛,发送信息到各大博客,各大b2b软件自动发布,好不夸张的说:只要手工能发在电脑打开IE能发的网站,用这个宣传软件就可以仿制动作,进行推送发到您想发送的B2B网站或是信息发布平台上,不管是后台,还是前台,都可以进行最方便的广告发布,这个广告发布软件,可以按月购买,还可以试用软件,对网站的验证码也可以完全自动对信息发布,让客户自动找上门,使企业轻松实现b2b发布,这个信息发布软件,均是本站原创正版开发,拥有正版的血统,想要新功能,欢迎提意见给我,一好的分类信息群发软件在手,舍我其谁。QQ896757558

GMT+8, 2026-2-24 23:41 , Processed in 0.470243 second(s), 51 queries .

宣传软件--信息发布软件--b2b软件广告发布软件

快速回复 返回顶部 返回列表