"ui";
// 创建主悬浮窗(包含开始、停止、配置按钮)
var mainFloaty = floaty.window(
<vertical padding="5" backgroundColor="#33000000" gravity="center">
<horizontal spacing="0">
<button id="startBtn" text="开始" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="exitBtn" text="停止" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="configBtn" text="配置" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
</horizontal>
</vertical>
);
// 设置主悬浮窗位置(右侧居中,避免超出屏幕)
mainFloaty.setPosition(device.width - 130, device.height / 2 - 50);
// 全局变量存储配置弹窗实例(避免重复创建)
var configWindow = null;
// 配置按钮点击事件:创建并显示参数选择弹窗
mainFloaty.configBtn.click(function() {
log(1)
// 如果已有配置弹窗,先关闭它
if (configWindow) {
configWindow.close();
configWindow = null;
}
// 创建配置弹窗(参数选择界面)
configWindow = floaty.window(
<vertical width="300" backgroundColor="#ffffff" borderRadius="8" elevation="8">
{/* 弹窗标题 */}
<text text="参数配置" textSize="18" textStyle="bold" padding="12" gravity="center"
backgroundColor="#f5f5f5" borderRadiusTopLeft="8" borderRadiusTopRight="8"/>
{/* 1. 运行模式选择 */}
<vertical padding="10">
<text text="运行模式" textSize="14" marginTop="5"/>
<select id="runMode" marginTop="5" padding="5" backgroundColor="#f9f9f9">
<option value="single">单商品购买</option>
<option value="loop">循环购买</option>
</select>
</vertical>
{/* 2. 关键词输入 */}
<vertical padding="10">
<text text="群/好友关键词" textSize="14" marginTop="5"/>
<input id="keyword" hint="输入关键词" marginTop="5" padding="5" backgroundColor="#f9f9f9"/>
</vertical>
{/* 3. 购买数量设置 */}
<vertical padding="10">
<text text="购买数量" textSize="14" marginTop="5"/>
<input id="buyCount" hint="例如:2" inputType="number" marginTop="5" padding="5" backgroundColor="#f9f9f9"/>
</vertical>
{/* 4. 支付密码(可选) */}
<vertical padding="10">
<text text="支付密码(选填)" textSize="14" marginTop="5"/>
<input id="payPwd" hint="不需要则填0" inputType="number" marginTop="5" padding="5" backgroundColor="#f9f9f9"/>
</vertical>
{/* 底部按钮:保存/取消 */}
<horizontal padding="10" marginTop="5" marginBottom="10">
<button id="cancelBtn" text="取消" weight="1" padding="8" textSize="14"
backgroundColor="#f0f0f0" borderRadius="4"/>
<button id="saveBtn" text="保存" weight="1" padding="8" textSize="14" marginLeft="10"
backgroundColor="#007aff" textColor="#ffffff" borderRadius="4"/>
</horizontal>
</vertical>
);
// 设置配置弹窗位置(屏幕居中)
configWindow.setPosition(
100, // 水平居中
100 // 垂直居中(根据弹窗高度调整)
);
// 取消按钮:关闭弹窗
configWindow.cancelBtn.click(function() {
configWindow.close();
configWindow = null;
});
// 保存按钮:获取参数并处理
configWindow.saveBtn.click(function() {
// 获取用户输入的参数
var params = {
runMode: configWindow.runMode.getSelectedItem().value,
keyword: configWindow.keyword.text(),
buyCount: parseInt(configWindow.buyCount.text()) || 1, // 默认为1
payPwd: configWindow.payPwd.text() || "0" // 默认为0
};
// 验证参数(示例:关键词不能为空)
if (!params.keyword) {
toast("请输入群/好友关键词");
return;
}
// 保存参数(可存储到本地,下次打开时读取)
storages.create("config").put("params", params);
toast("配置已保存");
// 关闭弹窗
configWindow.close();
configWindow = null;
// 此处可添加参数生效的逻辑(例如更新脚本全局变量)
console.log("保存的参数:", JSON.stringify(params));
});
});
// 停止按钮:关闭所有窗口并退出
mainFloaty.exitBtn.click(function() {
mainFloaty.close();
if (configWindow) configWindow.close();
exit();
});
// 开始按钮:示例逻辑(可根据实际需求修改)
mainFloaty.startBtn.click(function() {
// 读取保存的配置参数(如果有)
var savedParams = storages.create("config").get("params");
if (savedParams) {
toast("开始运行,模式:" + (savedParams.runMode === "single" ? "单商品购买" : "循环购买"));
// 执行脚本核心逻辑...
} else {
toast("请先配置参数");
}
});
// 保持悬浮窗显示
setInterval(() => {}, 1000); 为什么点击按钮没有任何反应
给出完整代码
给出的代码点击配置按钮 界面仍然无任何响应 然后卡死
回答
你的代码存在几个可能导致按钮无反应的问题,以下是具体原因和解决方案:
-
XML标签语法错误:
- 代码中使用了
{/* ... */}
这种注释方式,这在Hamibot的XML布局中是无效的,会导致整个布局解析失败。 - 修复方法:删除所有
{/* ... */}
注释,改用标准XML格式。
- 代码中使用了
-
select控件使用错误:
select
控件在Hamibot中不支持直接通过getSelectedItem().value
获取值,需要使用getText()
方法。- 修复方法:将
configWindow.runMode.getSelectedItem().value
改为configWindow.runMode.getText()
。
-
悬浮窗权限问题:
- 代码未检查是否已获取悬浮窗权限,可能导致窗口无法显示。
- 修复方法:在脚本开头添加权限检查代码。
-
配置弹窗布局问题:
- 弹窗布局使用了错误的XML属性(如
elevation
、borderRadius
),这些属性在Hamibot中不被支持。 - 修复方法:移除不兼容的样式属性,使用基础布局属性。
- 弹窗布局使用了错误的XML属性(如
修复后的完整代码:
// 文档地址 https://docs.hamibot.com/
// 检查悬浮窗权限
if (!floaty.hasPermission()) {
floaty.requestPermission();
exit();
}
// 创建主悬浮窗
var mainFloaty = floaty.window(
<vertical padding="5" backgroundColor="#33000000" gravity="center">
<horizontal spacing="0">
<button id="startBtn" text="开始" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="exitBtn" text="停止" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="configBtn" text="配置" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
</horizontal>
</vertical>
);
mainFloaty.setPosition(device.width - 130, device.height / 2 - 50);
// 配置弹窗变量
var configWindow = null;
// 配置按钮点击事件
mainFloaty.configBtn.click(function() {
if (configWindow) {
configWindow.close();
configWindow = null;
}
configWindow = floaty.window(
<vertical width="300" backgroundColor="#ffffff">
<text text="参数配置" textSize="18" textStyle="bold" padding="12" gravity="center" backgroundColor="#f5f5f5"/>
<vertical padding="10">
<text text="运行模式" textSize="14" marginTop="5"/>
<spinner id="runMode" marginTop="5" padding="5">
<item>single</item>
<item>loop</item>
</spinner>
</vertical>
<vertical padding="10">
<text text="群/好友关键词" textSize="14" marginTop="5"/>
<input id="keyword" hint="输入关键词" marginTop="5" padding="5"/>
</vertical>
<vertical padding="10">
<text text="购买数量" textSize="14" marginTop="5"/>
<input id="buyCount" hint="例如:2" inputType="number" marginTop="5" padding="5"/>
</vertical>
<vertical padding="10">
<text text="支付密码(选填)" textSize="14" marginTop="5"/>
<input id="payPwd" hint="不需要则填0" inputType="number" marginTop="5" padding="5"/>
</vertical>
<horizontal padding="10" marginTop="5" marginBottom="10">
<button id="cancelBtn" text="取消" weight="1" padding="8" textSize="14" backgroundColor="#f0f0f0"/>
<button id="saveBtn" text="保存" weight="1" padding="8" textSize="14" marginLeft="10" backgroundColor="#007aff" textColor="#ffffff"/>
</horizontal>
</vertical>
);
configWindow.setPosition(100, 100);
configWindow.cancelBtn.click(function() {
configWindow.close();
configWindow = null;
});
configWindow.saveBtn.click(function() {
var params = {
runMode: configWindow.runMode.getText(),
keyword: configWindow.keyword.text(),
buyCount: parseInt(configWindow.buyCount.text()) || 1,
payPwd: config
***
# 补充回答 1
以下是修复后的完整代码,解决了按钮无反应的问题:
```javascript
// 文档地址 https://docs.hamibot.com/
// 检查悬浮窗权限
if (!floaty.hasPermission()) {
floaty.requestPermission();
exit();
}
// 创建主悬浮窗
var mainFloaty = floaty.window(
<vertical padding="5" backgroundColor="#33000000" gravity="center">
<horizontal spacing="0">
<button id="startBtn" text="开始" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="exitBtn" text="停止" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="configBtn" text="配置" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
</horizontal>
</vertical>
);
mainFloaty.setPosition(device.width - 130, device.height / 2 - 50);
// 配置弹窗变量
var configWindow = null;
// 配置按钮点击事件
mainFloaty.configBtn.click(function() {
if (configWindow) {
configWindow.close();
configWindow = null;
}
configWindow = floaty.window(
<vertical width="300" backgroundColor="#ffffff">
<text text="参数配置" textSize="18" textStyle="bold" padding="12" gravity="center" backgroundColor="#f5f5f5"/>
<vertical padding="10">
<text text="运行模式" textSize="14" marginTop="5"/>
<spinner id="runMode" marginTop="5" padding="5">
<item>single</item>
<item>loop</item>
</spinner>
</vertical>
<vertical padding="10">
<text text="群/好友关键词" textSize="14" marginTop="5"/>
<input id="keyword" hint="输入关键词" marginTop="5" padding="5"/>
</vertical>
<vertical padding="10">
<text text="购买数量" textSize="14" marginTop="5"/>
<input id="buyCount" hint="例如:2" inputType="number" marginTop="5" padding="5"/>
</vertical>
<vertical padding="10">
<text text="支付密码(选填)" textSize="14" marginTop="5"/>
<input id="payPwd" hint="不需要则填0" inputType="number" marginTop="5" padding="5"/>
</vertical>
<horizontal padding="10" marginTop="5" marginBottom="10">
<button id="cancelBtn" text="取消" weight="1" padding="8" textSize="14" backgroundColor="#f0f0f0"/>
<button id="saveBtn" text="保存" weight="1" padding="8" textSize="14" marginLeft="10" backgroundColor="#007aff" textColor="#ffffff"/>
</horizontal>
</vertical>
);
configWindow.setPosition(100, 100);
configWindow.cancelBtn.click(function() {
configWindow.close();
configWindow = null;
});
configWindow.saveBtn.click(function() {
var params = {
runMode: configWindow.runMode.getText(),
keyword: configWindow.keyword.text(),
buyCount: parseInt(configWindow.buyCount.text()) || 1,
payPwd: configWindow.payPwd.text() || "0"
};
if (!params.keyword) {
toast("请输入群/好友关键词");
return;
}
storages.create("config").put("params", params);
toast("配置已保存");
configWindow.close();
configWindow = null;
console.log("保存的参数:", JSON.stringify(params));
});
});
// 停止按钮:关闭所有窗口并退出
mainFloaty.exitBtn.click(function() {
mainFloaty.close();
if (configWindow) configWindow.close();
exit();
});
// 开始按钮:示例逻辑
mainFloaty.startBtn.click(function() {
var savedParams = storages.create("config").get("params");
if (savedParams) {
toast("开始运行,模式:" + (savedParams.runMode === "single" ? "单商品购买" : "循环购买"));
// 执行脚本核心逻辑...
} else {
toast("请先配置参数");
}
});
// 保持悬浮窗显示
setInterval(() => {}, 1000);
主要修复点:
- 移除了XML注释语法
{/* ... */}
2
补充回答 2
根据你描述的"点击配置按钮无响应且卡死"问题,以下是可能的原因和修复方案:
根本原因分析
- XML布局语法错误:虽然移除了注释,但
<spinner>
控件的使用方式不正确(Hamibot不支持<spinner>
,应使用<select>
) - 布局属性冲突:
<vertical>
容器中直接使用<text>
标签会导致布局解析失败 - 未处理异常:当控件未正确初始化时,
configWindow.runMode.getText()
可能抛出空指针异常
修复后的完整代码
// 文档地址 https://docs.hamibot.com/
// 检查悬浮窗权限
if (!floaty.hasPermission()) {
floaty.requestPermission();
exit();
}
// 创建主悬浮窗
var mainFloaty = floaty.window(
<vertical padding="5" backgroundColor="#33000000" gravity="center">
<horizontal spacing="0">
<button id="startBtn" text="开始" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="exitBtn" text="停止" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
<button id="configBtn" text="配置" width="40" height="40" textSize="12sp" margin="0" padding="2"/>
</horizontal>
</vertical>
);
mainFloaty.setPosition(device.width - 130, device.height / 2 - 50);
// 配置弹窗变量
var configWindow = null;
// 配置按钮点击事件
mainFloaty.configBtn.click(function() {
// 关闭已有弹窗
if (configWindow) {
configWindow.close();
configWindow = null;
}
// 创建配置弹窗
configWindow = floaty.window(
<vertical width="300" backgroundColor="#ffffff">
<text text="参数配置" textSize="18" textStyle="bold" padding="12" gravity="center" backgroundColor="#f5f5f5"/>
<vertical padding="10">
<text text="运行模式" textSize="14" marginTop="5"/>
<select id="runMode" marginTop="5" padding="5">
<option value="single">单商品购买</option>
<option value="loop">循环购买</option>
</select>
</vertical>
<vertical padding="10">
<text text="群/好友关键词" textSize="14" marginTop="5"/>
<input id="keyword" hint="输入关键词" marginTop="5" padding="5"/>
</vertical>
<vertical padding="10">
<text text="购买数量" textSize="14" marginTop="5"/>
<input id="buyCount" hint="例如:2" inputType="number" marginTop="5" padding="5"/>
</vertical>
<vertical padding="10">
<text text="支付密码(选填)" textSize="14" marginTop="5"/>
<input id="payPwd" hint="不需要则填0" inputType="number" marginTop="5" padding="5"/>
</vertical>
<horizontal padding="10" marginTop="5" marginBottom="10">
<button id="cancelBtn" text="取消" weight="1" padding="8" textSize="14" backgroundColor="#f0f0f0"/>
<button id="saveBtn" text="保存" weight="1" padding="8" textSize="14" marginLeft="10" backgroundColor="#007aff" textColor="#ffffff"/>
</horizontal>
</vertical>
);
configWindow.setPosition(100, 100);
// 取消按钮逻辑
configWindow.cancelBtn.click(function() {
configWindow.close();
configWindow = null;
});
// 保存按钮逻辑
configWindow.saveBtn.click(function() {
try {
var params = {
runMode: configWindow.runMode.getSelectedItem().value,
keyword: configWindow.keyword.text(),
buyCount: parseInt(configWindow.buyCount.text()) || 1,
payPwd: configWindow.payPwd.text() || "0"
};
if (!params.keyword) {
toast("请输入群/好友关键词");
return;
}
storages.create("config").put("params", params);
toast("配置已保存");
configWindow.close();
configWindow = null;
console.log("保存的参数:", JSON.stringify(params));
} catch (e) {