dialogs 对话框
dialogs 对话框
dialogs 是 ScriptX 里这一套可编排对话框模块。它支持两种用法:
- 直接调高层函数,比如
dialogs.alert(...)、dialogs.confirm(...) - 先
dialogs.build(options)拿到一个对话框实例,再慢慢挂监听、改进度、手动show()
先记住这 13 条
- 这组能力现在的全局对象名是
dialogs。 dialogs.prompt(...)只是dialogs.input(...)的别名。- 如果你给
alert / confirm / input / select ...传了回调,它们会立刻返回null,然后异步等结果。 - 如果你不传回调,而且当前不在
ui页面宿主里,这些 API 会直接阻塞等待,并把结果作为返回值给你。 dialogs.build(options)只负责创建实例,不会自动弹出来;要么你自己dialog.show(),要么再awaitResult()。itemsSelectMode当前可识别的值只有select、single、multi这 3 类;single_choice、multichoice这种只是同义写法。dialog.getActionButton(action)/dialog.setActionButton(action, title)里的action现在只认positive、negative、neutral这 3 组名字和它们的常见别名。type/setDefaultDialogType(...)当前虽然能填app、overlay、foreground-or-overlay、app-or-overlay,但这套值现在主要是被标准化保存,实际展示流程还没有按它分出完全不同的渲染分支。- 当前实现依然要求“存在可用
Activity”;没有前台可用页面时,show()会直接抛错。 stubborn: true会强制把cancelable和canceledOnTouchOutside都改成false。rawInput(...)和input(...)当前在脚本层的返回行为基本一致,都会在确认时返回输入框文本。dialog.emit(...)只会触发你挂在这个实例上的 JS 监听器,不会代替真正的按钮点击。- 如果当前
Activity是ui模块创建出来的ScriptUiActivity,那么不传回调时不会走阻塞返回,而是返回一个带then / catch / finally的 Promise 风格对象。
ui 页面里的返回行为
这一条很重要,因为很多人会在普通脚本和 ui.layout(...) 页面之间来回切。
普通脚本环境
不传回调时,dialogs.confirm(...)、dialogs.input(...) 这些会:
- 先弹出对话框
- 当前脚本线程等待结果
- 最后直接把结果返回给你
也就是这种写法可以成立:
const confirmed = dialogs.confirm("删除", "确定继续吗?");
if (confirmed) {
log("继续");
}
ui 页面环境
如果当前页面来自 ui.layout(...) 这一套宿主,源码会改成 Promise 风格结果,而不是阻塞当前页面脚本。
也就是更稳的写法应该像这样:
dialogs.confirm("删除", "确定继续吗?").then(function (confirmed) {
if (confirmed) {
log("继续");
}
});
为什么文档要单独强调这件事
因为这会直接影响你写页面事件回调时的代码风格:
- 普通脚本里可以先调对话框,再立刻拿返回值
ui页面里更推荐then(...)/ 回调版
如果你把普通脚本的同步写法原样搬进 ui 页面,就容易出现“为什么这里拿到的不是布尔值”的困惑。
dialogs.setDefaultDialogType(value)
设置后续 dialogs.alert(...)、dialogs.confirm(...) 这些快捷 API 默认使用的对话框类型标记。
参数
| 参数 | 类型 | 可填值 | 默认值 |
|---|---|---|---|
value | string | app、overlay、foreground-or-overlay、app-or-overlay | app-or-overlay |
返回值
dialogs
这是一个可链式调用的方法。
真实说明
当前源码会把值标准化成下面 4 个之一:
| 你传入的值 | 最终保存值 |
|---|---|
app | app |
overlay | overlay |
foreground-or-overlay | foreground-or-overlay |
| 其他值、空值 | app-or-overlay |
但要注意,当前 dialogs 实现里,这个字段主要还是配置位,show() 逻辑本身还没有按这 4 种值拆成完全不同的弹出宿主。
示例
dialogs.setDefaultDialogType("app");
dialogs.alert("提示", "后面的快捷弹窗都会继承这个默认 type 标记");
dialogs.alert(title?, content?, callback?)
最简单的提示框。
参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | string | 空 | 标题 |
content | string | 空 | 正文 |
callback | function | 不传 | 传了就走异步 |
返回值
| 用法 | 返回值 |
|---|---|
| 不传回调,普通脚本环境 | boolean |
不传回调,ui 页面环境 | Promise 风格对象 |
| 传回调 | null |
结果规则
| 操作 | 返回结果 |
|---|---|
| 点正按钮 | true |
| 取消 / 关闭 / 点返回 | false |
示例
const ok = dialogs.alert("提示", "脚本已经启动");
log(ok); // true 或 false
dialogs.alert("提示", "异步回调版", function () {
log("用户点掉了 alert");
});
dialogs.confirm(title?, content?, callback?)
确认框。
返回值
| 用法 | 返回值 |
|---|---|
| 不传回调 | boolean |
| 传回调 | null |
结果规则
| 操作 | 返回结果 |
|---|---|
| 点“确定” | true |
| 点“取消”、关闭、返回 | false |
示例
const confirmed = dialogs.confirm("删除", "确定要继续吗?");
if (confirmed) {
log("继续执行");
}
dialogs.confirm("删除", "确定要继续吗?").then(function (confirmed) {
if (confirmed) {
log("继续执行");
}
});
dialogs.rawInput(title?, prefill?, callback?)
弹一个输入框,确认时返回当前输入文本。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
title | string | 标题 |
prefill | string | 预填文字 |
callback | function | 异步回调 |
返回值
| 用法 | 返回值 |
|---|---|
| 不传回调,普通脚本环境 | string | null |
不传回调,ui 页面环境 | Promise 风格对象 |
| 传回调 | null |
结果规则
- 点“确定”:返回输入框内容
- 取消 / 关闭:返回
null
示例
const text = dialogs.rawInput("请输入手机号", "138");
log(text);
dialogs.rawInput("请输入手机号", "138").then(function (text) {
log(text);
});
dialogs.input(title?, prefill?, callback?)
输入框快捷入口。
返回值
当前脚本层实现里,它和 dialogs.rawInput(...) 的结果规则一致:
- 确认时返回字符串
- 取消时返回
null
在 ui 页面里,不传回调时同样会返回 Promise 风格对象。
示例
const keyword = dialogs.input("搜索", "微信");
if (keyword != null) {
log(`keyword=${keyword}`);
}
dialogs.input("搜索", "微信").then(function (keyword) {
if (keyword != null) {
log(`keyword=${keyword}`);
}
});
dialogs.prompt(title?, prefill?, callback?)
dialogs.input(...) 的别名。
示例
const name = dialogs.prompt("昵称", "ScriptX");
dialogs.select(title?, items, callback?)
单次点击即完成的列表选择框。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
title | string | 标题 |
items | array | 列表项 |
callback | function(index, item) | 可选 |
返回值
| 用法 | 返回值 |
|---|---|
| 不传回调 | number |
| 传回调 | null |
结果规则
| 情况 | 返回值 |
|---|---|
| 点中某项 | 该项索引 |
| 取消 / 关闭 | -1 |
回调参数
如果你传了回调,当前会回调:
function (index, item) {}
示例
const index = dialogs.select("请选择模式", ["正常", "快速", "调试"]);
log(index);
dialogs.select("请选择模式", ["正常", "快速"], function (index, item) {
log(`index=${index}, item=${item}`);
});
dialogs.singleChoice(title, items, selectedIndex?, callback?)
带单选态的列表框。
参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | string | 空 | 标题 |
items | array | [] | 列表项 |
selectedIndex | number | -1 | 初始选中项 |
callback | function(index, item) | 不传 | 异步回调 |
返回值
| 用法 | 返回值 |
|---|---|
| 不传回调 | number |
| 传回调 | null |
结果规则
- 点“确定”:返回当前选中的索引
- 取消 / 关闭:返回
-1
示例
const index = dialogs.singleChoice("主题", ["亮色", "暗色"], 1);
log(index);
dialogs.multiChoice(title, items, selectedIndices?, callback?)
多选列表框。
参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | string | 空 | 标题 |
items | array | [] | 列表项 |
selectedIndices | array<number> | [] | 初始选中索引 |
callback | function(indices, items) | 不传 | 异步回调 |
返回值
| 用法 | 返回值 |
|---|---|
| 不传回调 | number[] |
| 传回调 | null |
结果规则
- 点“确定”:返回排序后的索引数组
- 取消 / 关闭:返回空数组
[]
示例
const indices = dialogs.multiChoice("选择导出项", ["日志", "截图", "配置"], [0, 2]);
log(JSON.stringify(indices));
dialogs.build(options)
创建一个更可控的对话框实例。
参数总表
| 字段 | 类型 | 可填值 / 默认值 | 说明 |
|---|---|---|---|
title / heading | string | 空 | 标题 |
content / message / body | string | 空 | 正文 |
positive | string | 空 | 正按钮文案 |
negative | string | 空 | 负按钮文案 |
neutral | string | 空 | 中立按钮文案 |
titleColor | 颜色值 | 可解析颜色 | 标题颜色 |
contentColor | 颜色值 | 可解析颜色 | 正文颜色 |
itemsColor | 颜色值 | 可解析颜色 | 当前已解析但还没有单独样式落点 |
positiveColor | 颜色值 | 可解析颜色 | 正按钮文字色 |
negativeColor | 颜色值 | 可解析颜色 | 负按钮文字色 |
neutralColor | 颜色值 | 可解析颜色 | 中立按钮文字色 |
contentLineSpacing | number | 空 | 最终传给 TextView.setLineSpacing(add, 1f) 的附加间距 |
icon | Drawable | number | Image | Bitmap | string | 空 | 资源 id、位图、图片对象、或本地图片路径 |
items | array | [] | 列表项 |
itemsSelectMode | string | select / single / multi | 列表选择模式 |
itemsSelectedIndex | number | -1 | 单选初值 |
itemsSelectedIndices / selectedIndices | array<number> | [] | 多选初值 |
cancelable | boolean | true | 是否可取消 |
canceledOnTouchOutside | boolean | 默认跟随 cancelable | 点外部是否关闭 |
autoDismiss | boolean | true | 结果触发后是否自动关闭 |
inputHint | string | 空 | 输入框提示 |
inputPrefill | string | 空 | 输入框默认内容 |
checkBoxPrompt | string | 空 | 复选框文案 |
checkBoxChecked | boolean | false | 复选框默认状态 |
progress | number | 空 | 进度值 |
maxProgress | number | 空 | 最大进度 |
progressIndeterminate | boolean | false | 是否不定进度 |
customView | View | 空 | 自定义 Android View |
wrapInScrollView | boolean | false | 只包裹 customView |
stubborn | boolean | false | 为 true 时强制不可取消 |
type | string | app / overlay / foreground-or-overlay / app-or-overlay | 对话框类型标记 |
itemsSelectMode 到底认哪些值
| 你传的值 | 最终模式 |
|---|---|
single / single_choice / singlechoice | single |
multi / multi_choice / multichoice | multi |
| 其他值 | select |
布尔字段认哪些值
当前 dialogs 里的布尔解析比较宽:
| 写法 | 会被当成 |
|---|---|
true / 1 / "true" / "1" / "yes" / "on" | true |
false / 0 / "false" / "0" / "no" / "off" | false |
icon 支持哪些形式
| 写法 | 说明 |
|---|---|
| 资源 id 数字 | 当 Android drawable 资源 id 用 |
Drawable | 直接使用 |
Image | 取图片位图包装成 BitmapDrawable |
Bitmap | 直接包装成 BitmapDrawable |
| 本地路径字符串 | 文件存在才会加载,否则忽略 |
返回值
dialog
也就是一个 ScriptX 包装过的对话框实例对象。
示例
const dialog = dialogs.build({
title: "下载进度",
content: "正在准备资源",
positive: "完成",
negative: "取消",
progress: 10,
maxProgress: 100,
cancelable: false
});
对话框实例对象
下面这些方法都挂在 dialogs.build(...) 返回的 dialog 实例上。
dialog.show()
显示对话框。
返回值
dialog
注意
当前实现需要可用 Activity。拿不到时会抛:
dialogs 需要当前存在可用的 Activity
dialog.dismiss()
关闭对话框。
返回值
dialog
dialog.isShowing()
当前是否还在显示。
返回值
boolean
dialog.getTitleView()
拿标题 View。
返回值
View | null
dialog.getContentView()
拿正文或你设置的自定义内容 View。
返回值
View | null
dialog.getInputEditText()
拿输入框控件。
返回值
EditText | null
dialog.getItems()
拿你传进去的 items 副本。
返回值
array
dialog.getProgress()
读当前进度值。
返回值
number
dialog.setProgress(value)
改当前进度。
参数
非数字会按 0 处理,小于 0 会被抬到 0。
返回值
dialog
dialog.getMaxProgress()
读最大进度。
返回值
number
dialog.setMaxProgress(value)
改最大进度。
返回值
dialog
dialog.setActionButton(action, title)
动态改按钮文案。
action 可填值
| 可填值 | 实际按钮 |
|---|---|
positive / ok / confirm | 正按钮 |
negative / cancel | 负按钮 |
neutral | 中立按钮 |
返回值
dialog
dialog.getActionButton(action)
拿某个按钮的真实 View。
返回值
View | null
dialog.on(eventName, listener)
给对话框实例挂一个持久监听。
返回值
dialog
dialog.once(eventName, listener)
挂一个一次性监听。
返回值
dialog
dialog.emit(eventName, ...args)
手动触发实例上的 JS 监听器。
返回值
boolean
说明
- 有监听器被触发时返回
true - 没监听器时返回
false
dialog.removeListener(eventName, listener)
移除某个监听器。
返回值
dialog
dialog.off(eventName, listener)
removeListener(...) 的别名。
dialog.removeAllListeners(eventName?)
移除全部监听器。
返回值
dialog
dialog.onResult(listener)
在最终结果落地时收到一次回调。
返回值
dialog
dialog.awaitResult()
阻塞等待最终结果。
返回值
结果类型取决于你构建的对话框内容和触发方式。
dialog 实例里常见的事件名
| 事件名 | 什么时候触发 | 参数 |
|---|---|---|
show | 对话框显示后 | 无 |
cancel | 被取消时 | 无 |
dismiss | 被关闭时 | 无 |
positive | 点正按钮时 | 无 |
negative | 点负按钮时 | 无 |
neutral | 点中立按钮时 | 无 |
item_select | select 模式点某项时 | index, item |
single_choice | 单选列表选择变化时 | index, item |
multi_choice | 多选变化时 | indices, items |
input_change | 输入框内容变化时 | text |
check | 复选框变化时 | boolean |
result | 最终结果确定时 | value |
例子
const dialog = dialogs.build({
title: "测试",
inputHint: "请输入",
positive: "确定",
negative: "取消"
});
dialog.on("input_change", function (text) {
log(`now=${text}`);
});
dialog.on("result", function (value) {
log(`result=${value}`);
});
dialog.show();
一段完整示例
const dialog = dialogs.build({
title: "导出设置",
content: "请选择需要导出的内容",
items: ["日志", "截图", "配置"],
itemsSelectMode: "multi",
itemsSelectedIndices: [0, 2],
positive: "开始导出",
negative: "取消",
progress: 0,
maxProgress: 100,
autoDismiss: false
});
dialog.on("multi_choice", function (indices, items) {
log(`indices=${JSON.stringify(indices)} items=${JSON.stringify(items)}`);
});
dialog.on("positive", function () {
dialog.setProgress(30);
});
dialog.onResult(function (result) {
log(`final=${JSON.stringify(result)}`);
});
dialog.show();
最后再提醒一个边界
type 这一项现在已经有明确可填值,但当前这版 dialogs 真正显示时,仍然是先找“当前可用 Activity”来弹。
所以你现在应该把它理解成:
- 这是一个已经存在的配置位
- 文档要把可填值写清楚
- 但不能把它吹成“已经有 4 套完全不同的展示宿主”
这一点和很多只看字段名就下结论的文档不一样,这里按当前源码实际行为说。
