"ui";
var config_ui_view = ui.layout(
<vertical padding="16" layout_height="match_parent">
<card layout_width="match_parent" cardBackgroundColor="#ffffff" cardCornerRadius="12" cardElevation="4" padding="20dp" margin="10dp">
<scroll layout_width="match_parent" layout_height="600dp" padding="5dp">
<vertical>
<text text="数量" textSize="17sp" marginBottom="8dp"/>
<input id="text_number" hint="例如填2" inputType="number" layout_width="match_parent" layout_height="45dp" marginTop="0dp" padding="10dp" backgroundColor="#f9f9f9" marginBottom="15dp" focusable="true" focusableInTouchMode="true"/>
<text text="最大刷新次数" textSize="17sp" marginBottom="8dp"/>
<input id="text_timeoutcount" hint="建议5000+" inputType="number" layout_width="match_parent" layout_height="45dp" marginTop="0dp" padding="10dp" backgroundColor="#f9f9f9" marginBottom="15dp" focusable="true" focusableInTouchMode="true"/>
<text text="单次刷新延时" textSize="17sp" marginBottom="8dp"/>
<input id="text_refush_timeout" hint="单位为ms(1s=1000ms)" inputType="number" layout_width="match_parent" layout_height="45dp" marginTop="0dp" padding="10dp" backgroundColor="#f9f9f9" marginBottom="15dp" focusable="true" focusableInTouchMode="true"/>
<text text="2刷总执行时长" textSize="17sp" marginBottom="8dp"/>
<input id="text_refush_timeout_tow" hint="单位为s,建议600-900" inputType="number" layout_width="match_parent" layout_height="45dp" marginTop="0dp" padding="10dp" backgroundColor="#f9f9f9" marginBottom="15dp" focusable="true" focusableInTouchMode="true"/>
<text text="2刷模式" textSize="17sp" marginBottom="8dp"/>
<spinner id="select_runtype_refush_two" layout_width="match_parent" layout_height="45dp" entries="正常模式|无跳转模式|快速模式" marginTop="0dp" padding="10dp" backgroundColor="#f9f9f9" marginBottom="15dp" focusable="true"/>
<text text="无跳转模式每次动作延时" textSize="17sp" marginBottom="8dp"/>
<input id="text_refush_timeout_tow_delay" hint="单位为ms,建议100-200" inputType="number" layout_width="match_parent" layout_height="45dp" marginTop="0dp" padding="10dp" backgroundColor="#f9f9f9" marginBottom="20dp" focusable="true" focusableInTouchMode="true"/>
<horizontal padding="16" marginTop="16" layout_width="match_parent" layout_height="150dp">
<button id="saveBtn" text="保存配置" layout_weight="1" backgroundColor="#4CAF50" textColor="#ffffff" textSize="16sp" padding="10dp" borderRadius="6dp"/>
<button id="runBtn" text="关闭配置" layout_weight="1" marginLeft="8dp" backgroundColor="#2196F3" textColor="#ffffff" textSize="16sp" padding="10dp" borderRadius="6dp"/>
</horizontal>
</vertical>
</scroll>
</card>
</vertical>
);
if (android.provider.Settings.canDrawOverlays(context)) {
toastLog('已获得悬浮窗权限');
} else {
toastLog('未获得悬浮窗权限');
}
// 日志悬浮窗(左侧初始位置,高度为屏幕5%)
let display = context.getResources().getDisplayMetrics();
let screenWidth = display.widthPixels; // 获取屏幕宽度
let screenHeight = display.heightPixels; // 获取屏幕高度
// 计算窗口大小:宽度为屏幕10%,高度为屏幕5%
let windowWidth = Math.round(screenWidth * 0.1);
let windowHeight = Math.round(screenHeight * 0.05);
// 确保窗口有最小尺寸
windowWidth = Math.max(windowWidth, 150);
windowHeight = Math.max(windowHeight, 80);
let logWindow = floaty.rawWindow(
<vertical w={windowWidth} h={windowHeight} bg="#CC333333" padding="0" radius="8" elevation="8">
<horizontal id="titleBar" w="" h="30" bg="#444444" gravity="center_vertical" paddingLeft="10" paddingRight="10">
<text textColor="#ffffff" textSize="14sp" >日志信息</text>
<button id="closeBtn" text="关闭" textSize="8sp" w="35" h="35"
bg="#444444" textColor="#ffffff"
rippleColor="#66ffffff"
pressedColor="#555555"/>
</horizontal>
<com.stardust.autojs.core.console.ConsoleView
id="console"
layout_weight="1"
w=""
bg="#AA222222"
/>
</vertical>
);
ui.setContentView(logWindow) 为什么只显示日志窗口 ui.layout 内容不显示
那点击悬浮窗某个按钮后要显示一个参数界面 这该用ui 还是 浮窗
// 主悬浮窗(包含按钮)
var floatyWin = floaty.window(
<vertical>
<button id="configBtn" text="打开参数设置" />
</vertical>
);
// 点击按钮后显示参数界面
floatyWin.configBtn.click(function () {
// 创建参数界面悬浮窗
var configWindow = floaty.window(
<vertical padding="16" bg="#ffffff" w="300" h="400">
<text text="参数设置" textSize="18sp" marginBottom="16" />
<input id="paramInput" hint="输入参数" inputType="text" />
<button id="saveBtn" text="保存" marginTop="20" />
</vertical>
);
// 保存按钮事件
configWindow.saveBtn.click(function () {
var value = configWindow.paramInput.getText();
toast("保存参数: " + value);
configWindow.close(); // 关闭参数界面
});
}); 给出的代码运行后 参数界面 填写数据 并不能唤起输入法 无法输入内容
回答
你的代码中存在两个独立的界面创建逻辑,导致 ui.layout
定义的内容被 floaty.rawWindow
创建的悬浮窗覆盖或未正确渲染。以下是具体原因和解决方案:
原因分析
-
ui.setContentView(logWindow)
仅设置悬浮窗内容floaty.rawWindow
创建的是一个独立的浮动窗口,其内容通过<vertical>
标签定义。ui.setContentView(logWindow)
会将主界面替换为这个浮动窗口,导致之前通过ui.layout
定义的界面(如config_ui_view
)被覆盖。
-
ui.layout
未正确附加到视图- 你定义了
config_ui_view
但未调用ui.show()
或ui.setContentView(config_ui_view)
,因此该界面未被显示。
- 你定义了
-
悬浮窗与主界面冲突
- 浮动窗口(
floaty.rawWindow
)通常以系统级窗口形式存在,可能覆盖主界面,导致ui.layout
内容不可见。
- 浮动窗口(
解决方案
方案 1:仅显示悬浮窗(推荐)
如果目标是只显示日志悬浮窗,需移除 ui.layout
的定义,直接使用 floaty.rawWindow
:
// 删除 config_ui_view 的 layout 定义
// 保留悬浮窗逻辑
let logWindow = floaty.rawWindow(
<vertical w="100%" h="100%" bg="#CC333333" padding="0" radius="8" elevation="8">
<horizontal id="titleBar" w="*" h="30" bg="#444444" gravity="center_vertical" paddingLeft="10" paddingRight="10">
<text textColor="#ffffff" textSize="14sp">日志信息</text>
<button id="closeBtn" text="关闭" textSize="8sp" w="35" h="35"
bg="#444444" textColor="#ffffff"
rippleColor="#66ffffff"
pressedColor="#555555"/>
</horizontal>
<com.stardust.autojs.core.console.ConsoleView
id="console"
layout_weight="1"
w="*"
bg="#AA222222"
/>
</vertical>
);
ui.setContentView(logWindow);
方案 2:同时显示主界面和悬浮窗
若需同时显示 ui.layout
和悬浮窗,需确保两者独立且不冲突:
// 显示主界面
var config_ui_view = ui.layout(
<vertical padding="16" layout_height="match_parent">
<!-- 你的布局内容 -->
</vertical>
);
ui.show(); // 显示主界面
// 创建悬浮窗(需确保不覆盖主界面)
let logWindow = floaty.rawWindow(
<vertical w="100%" h="100%" bg="#CC333333" padding="0" radius="8" elevation="8">
<!-- 悬浮窗内容 -->
</vertical>
);
logWindow.show(); // 显示悬浮窗
方案 3:检查悬浮窗尺寸与位置
如果悬浮窗尺寸过大或位置错误,可能导致主界面被遮挡:
// 调整悬浮窗尺寸为屏幕的 10% 宽度和 5% 高度
let display = context.getResources().getDisplayMetrics();
let screenWidth = display.widthPixels;
let screenHeight = display.heightPixels;
let windowWidth = Math.round(screenWidth * 0.1);
let windowHeight = Math.round(screenHeight * 0.05);
windowWidth = Math.max(windowWidth, 150);
windowHeight = Math.max(windowHeight, 80);
let logWindow = floaty.rawWindow(
<vertical w={windowWidth} h={windowHeight} ... />
);
关键注意事项
ui.setContentView
仅适用于主界面:若需显示浮动窗口,应使用floaty.rawWindow().show()
。- 避免同时设置主界面和浮动窗口:浮动窗口可能覆盖主界面,导致
ui.layout
内容不可见。 - 检查权限:确保已获取
悬浮窗权限
,否则浮动窗口无法显示。
如果问题仍未解决,建议提供完整的脚本逻辑或截图进一步分析。
补充回答 1
在点击悬浮窗按钮后需要显示参数界面时,推荐使用 floaty.window
或 floaty.rawWindow
创建独立的浮动窗口,而不是通过 ui.layout
显示主界面。以下是具体分析和实现方式:
为什么选择悬浮窗而非 ui.layout
?
-
悬浮窗的全局性
ui.layout
创建的界面是应用内的普通视图,可能被系统限制(如后台任务中无法正常显示)。- 悬浮窗(
floaty.window
)以系统级窗口形式存在,能确保在任何界面之上显示,适合参数配置等需要强交互的场景。
-
避免界面冲突
- 如果主界面(
ui.layout
)已显示,再通过ui.setContentView
或ui.show()
弹出参数界面可能导致层级混乱或被覆盖。 - 悬浮窗可独立控制显示/隐藏,不会干扰主界面。
- 如果主界面(
实现方案:点击悬浮窗按钮后显示参数界面
以下代码示例演示如何通过 floaty.window
创建参数界面:
// 主悬浮窗(包含按钮)
var floatyWin = floaty.window(
<vertical>
<button id="configBtn" text="打开参数设置" />
</vertical>
);
// 点击按钮后显示参数界面
floatyWin.configBtn.click(function () {
// 创建参数界面悬浮窗
var configWindow = floaty.window(
<vertical padding="16" bg="#ffffff" w="300" h="400">
<text text="参数设置" textSize="18sp" marginBottom="16" />
<input id="paramInput" hint="输入参数" inputType="text" />
<button id="saveBtn" text="保存" marginTop="20" />
</vertical>
);
// 保存按钮事件
configWindow.saveBtn.click(function () {
var value = configWindow.paramInput.getText();
toast("保存参数: " + value);
configWindow.close(); // 关闭参数界面
});
});
关键注意事项
-
悬浮窗层级控制
- 使用
floaty.window
创建的界面会自动置顶,但需确保未开启系统「自动管理悬浮窗」功能(部分手机会限制第三方悬浮窗层级)。
- 使用
-
性能优化
- 避免频繁创建和销毁悬浮窗,可复用已有的窗口对象(例如通过
window.isVisible()
判断是否已显示)。
- 避免频繁创建和销毁悬浮窗,可复用已有的窗口对象(例如通过
-
权限检查
- 确保已通过
android.provider.Settings.canDrawOverlays(context)
检查并获取悬浮窗权限,否则无法显示。
- 确保已通过
如果必须使用 ui.layout
的情况
若参数界面需与主界面深度集成(如嵌入到当前应用的布局中),可通过以下方式实现:
// 主界面布局
var mainUi = ui.layout(
<vertical>
<button id="configBtn" text="打开参数设置" />
</vertical>
);
mainUi.show();
// 点击按钮后显示参数界面
mainUi.configBtn.click(function () {
// 创建参数界面(需在 UI 线程中执行)
ui.run(function () {
var configUi = ui.layout(
<vertical padding="16">
<input id="paramInput" hint="输入参数" />
<button id="saveBtn" text="保存" />
</vertical>
);
configUi.show();
});
});
但需注意:ui.layout
在后台脚本中可能无法正常显示,建议优先使用悬浮窗方案。
补充回答 2
在 floaty.window
创建的悬浮窗中,<input>
控件无法唤起输入法的常见原因是 未正确设置焦点属性 或 未触发输入法显示逻辑。以下是详细原因和解决方案:
原因分析
-
<input>
控件未启用焦点- 默认情况下,部分悬浮窗布局可能未正确设置
focusable
和focusableInTouchMode
属性,导致输入框无法获取焦点。 - 示例代码中未显式设置这些属性,可能被系统判定为不可交互。
- 默认情况下,部分悬浮窗布局可能未正确设置
-
输入法未被触发
- 即使输入框获得焦点,也可能需要手动触发输入法弹出(如调用
input.showSoftInput()
)。
- 即使输入框获得焦点,也可能需要手动触发输入法弹出(如调用
-
悬浮窗层级问题
- 某些设备或系统版本中,悬浮窗可能因层级限制无法正常显示输入法。
解决方案
1. 修正 <input>
控件属性
确保 input
控件显式设置 focusable
和 focusableInTouchMode
为 true
:
var configWindow = floaty.window(
<vertical padding="16" bg="#ffffff" w="300" h="400">
<text text="参数设置" textSize="18sp" marginBottom="16" />
<input
id="paramInput"
hint="输入参数"
inputType="text"
focusable="true"
focusableInTouchMode="true"
/>
<button id="saveBtn" text="保存" marginTop="20" />
</vertical>
);
2. 手动触发输入法
在创建悬浮窗后,主动请求焦点并显示输入法:
floatyWin.configBtn.click(function () {
var configWindow = floaty.window(
<vertical padding="16" bg="#ffffff" w="300" h="400">
<text text="参数设置" textSize="18sp" marginBottom="16" />
<input
id="paramInput"
hint="输入参数"
inputType="text"
focusable="true"
focusableInTouchMode="true"
/>
<button id="saveBtn" text="保存" marginTop="20" />
</vertical>
);
// 主动请求焦点并显示输入法
ui.run(function () {
configWindow.paramInput.requestFocus();
// 触发输入法(需配合系统API)
// 注意:某些环境可能需要额外处理
});
// 保存按钮事件
configWindow.saveBtn.click(function () {
var value = configWindow.paramInput.getText();
toast("保存参数: " + value);
configWindow.close();
});
});
3. 使用 floaty.rawWindow
替代 floaty.window
如果上述方法无效,尝试改用 floaty.rawWindow
创建原始悬浮窗,其对输入法的支持更接近原生窗口:
var configWindow = floaty.rawWindow(
<vertical padding="16" bg="#ffffff" w="300" h="400">
<text text="参数设置" textSize="18sp" marginBottom="16" />
<input
id="paramInput"
hint="输入参数"
inputType="text"
focusable="true"
focusableInTouchMode="true"
/>
<button id="saveBtn" text="保存" marginTop="20" />
</vertical>
);
4. 检查系统权限
确保脚本已获取 悬浮窗权限 和 输入法权限:
if (android.provider.Settings.canDrawOverlays(context)) {
toastLog('已获得悬浮窗权限');
} else {
toastLog('未获得悬浮窗权限,请手动开启');
}
最终代码示例
// 主悬浮窗
var floatyWin = floaty.window(
<vertical>
<button id="configBtn" text="打开参数设置" />
</vertical>
);
// 点击按钮后显示参数界面
floatyWin.configBtn.click(function () {
var configWindow = floaty.window(
<vertical padding="16" bg="#ffffff" w="300" h="400">
<text text="参数设置" textSize="18sp" marginBottom="16" />
<input
id="paramInput"
hint="输入参数"
inputType="text"
focusable="true