-
Notifications
You must be signed in to change notification settings - Fork 223
基础对话框 MessageDialog 和 输入对话框 InputDialog
🌐 View English Document | 繁體中文文檔
基础对话框组件可以实现基本的对话框业务逻辑,包含标题、消息文本、单/双/三按钮的提醒功能,三个按钮可以按照纵向/横向进行显示,满足绝大部分日常阻断式提醒需求。
输入对话框 InputDialog 是基础对话框的扩展组件,除了包含基础的功能外还提供了输入框,可自定义输入提示文本、输入文字样式和点击按钮后的输入内容回调等。
使用以下代码显示一个对话框:
MessageDialog.show("标题", "正文内容", "确定");
请注意,标题、正文内容都可以传入 null,则不会显示相应的文本布局。
显示多个按钮的对话框:
MessageDialog.show("标题", "正文内容", "确定", "取消", "其他");
若需要将按钮显示为纵向的,可以通过以下代码设置:
MessageDialog messageDialog = new MessageDialog("标题", "正文内容", "确定", "取消", "其他")
.setButtonOrientation(LinearLayout.VERTICAL);
messageDialog.show();
通过上述代码您可以看到,对话框组件可以通过 .show(...)
静态方法直接创建并显示,也可以通过new
进行创建,另外要创建一个空的对话框,您可以使用 MessageDialog.build()
来实例化对话框对象。
若您在项目中引入了多个主题,需要临时改变某一个对话框的主题,亦或者是需要临时改变对话框的亮色和暗色模式,那么必须使用非“show”的方法创建,修改主题或颜色后再显示,方法如下:
MessageDialog.build()
.setStyle(IOSStyle.style())
.setTheme(DialogX.THEME.DARK)
.setTitle("标题")
.setMessage("内容")
.setOkButton("确定")
.show();
除此之外,你也可以使用 new 指令来构建 MessageDialog 和 InputDialog,DialogX 的对话框支持多种构建方式,随你所想,随你所用。
new MessageDialog()
.setTitle("标题")
.setMessage("内容")
.setOkButton("确定")
.show();
按钮回调可以通过方法进行设置:
MessageDialog.show("标题", "正文内容", "确定").setOkButton(new OnDialogButtonClickListener<MessageDialog>() {
@Override
public boolean onClick(MessageDialog baseDialog, View v) {
toast("点击确定按钮");
return false;
}
});
回调中有一个返回值,若return true
则可以点击后不自动关闭对话框。
另外,DialogX 还提供了多种设置回调和按钮文本的方法:
//只设置按钮文本
.setOkButton("确定")
//只设置按钮点击回调
.setOkButton(new OnDialogButtonClickListener<MessageDialog>() {
@Override
public boolean onClick(MessageDialog baseDialog, View v) {
toast("点击确定按钮");
return false;
}
});
//设置按钮文本并设置回调
.setOkButton("确定", new OnDialogButtonClickListener<MessageDialog>() {
@Override
public boolean onClick(MessageDialog baseDialog, View v) {
toast("点击确定按钮");
return false;
}
});
//隐藏按钮
.setOkButton(null)
请依据个人喜好随意使用。
如果你的业务流程中,并不需要对用户操作立即进行处理,但需要知道用户选择了哪个按钮,你也可以通过持有对话框句柄,在后续获取选择的状态,例如:
private MessageDialog dialog;
//业务流程模拟,创建并显示了一个对话框,但不立即处理点击事务
dialog = MessageDialog.show("Title", "Ask Question", "OK", "NO", "OTHER");
//需要时可根据 getButtonSelectResult() 方法获取用户点击了哪个按钮选项
BUTTON_SELECT_RESULT result = dialog.getButtonSelectResult();
BUTTON_SELECT_RESULT 是一个枚举,它包含以下类型:
NONE, //未做出选择
BUTTON_OK, //选择了确定按钮
BUTTON_CANCEL, //选择了取消按钮
BUTTON_OTHER //选择了其他按钮
你可以根据它的状态判断用户点击了哪个按钮。
基于这个特性,如果业务流程中针对用户的选择,无论选择哪个选项都有相同部分的代码需要执行,那么开发者也可以在用户选择后,例如在 DialogLifecycle#onDismiss
对话框的关闭事件中对用户的选择进行统一处理,减少重复代码量;
InputDialog 的回调与 MessageDialog 的回调略有不同,在回调参数中个给出了输入文本内容,方便直接判断和获取输入的文本:
new InputDialog("标题", "正文内容", "确定", "取消", "正在输入的文字")
.setCancelable(false)
.setOkButton(new OnInputDialogButtonClickListener<InputDialog>() {
@Override
public boolean onClick(InputDialog baseDialog, View v, String inputStr) {
toast("输入的内容:" + inputStr);
return false;
}
})
.show();
另外你也可以使用 inputDialog.getInputText()
来获取输入的文本内容。
想要监控对话框的生命周期,可以实现其 .setDialogLifecycleCallback(...)
接口,建议使用build()
方法构建对话框:
MessageDialog.build()
.setDialogLifecycleCallback(new DialogLifecycleCallback<MessageDialog>() {
@Override
public void onShow(MessageDialog dialog) {
//对话框启动时回调
}
@Override
public void onDismiss(MessageDialog dialog) {
//对话框关闭时回调
}
})
.show();
MessageDialog/InputDialog 也支持 Lifecycle,你可以使用 .getLifecycle()
获取 Lifecycle 对象。
你也可以通过使用 new 构建实例时,override 的生命周期事件的方式来处理生命周期事务,例如:
//复写事件演示
new MessageDialog() {
@Override
public void onShow(MessageDialog dialog) {
//...
tip("onShow");
}
@Override
public void onDismiss(MessageDialog dialog) {
//...
tip("onDismiss");
}
}
你也可以使用方法 .onShow(DialogXRunnable)
和 .onDismiss(DialogXRunnable)
,来处理生命周期事务,例如:
MessageDialog.show("title", "content", "ok")
.onShow(new DialogXRunnable<MessageDialog>() {
@Override
public void run(MessageDialog dialog) {
//MessageDialog show!
}
})
.onDismiss(new DialogXRunnable<MessageDialog>() {
@Override
public void run(MessageDialog dialog) {
//MessageDialog dismiss!
}
})
.show();
要实现在对话框中加入自定义布局,请先准备好自定义布局文件,然后使用以下方法构建:
MessageDialog.show("这里是标题", "此对话框演示的是自定义对话框内部布局的效果", "确定", "取消")
.setCustomView(new OnBindView<MessageDialog>(R.layout.layout_custom_view) {
@Override
public void onBind(MessageDialog dialog, View v) {
//View childView = v.findViewById(resId)...
}
});
回调参数中,v
为您给定的布局文件的实例化组件,您可以通过 v.findViewById(resId)
来实例化其他子布局组件,并在 onBind
方法中设置其功能和事件回调。
使用 ViewBinding 的话也可以更换为 OnBindingView 来实现直接通过 binding 获取布局实例:
MessageDialog.show("这里是标题", "此对话框演示的是自定义对话框内部布局的效果", "确定", "取消")
.setCustomView(new OnBindingView<MessageDialog, LayoutCustomViewBinding>() {
@Override
public void onBind(MessageDialog dialog, View view, LayoutCustomViewBinding binding) {
//View childView = binding.childView
}
});
MessageDialog.build()
.setTitle("标题")
.setMessage("这里是正文内容。")
.setOkButton("确定")
.setCancelButton("取消")
//设置入场动画资源和出场动画资源
.setAnimResId(R.anim.anim_dialogx_bottom_enter, R.anim.anim_dialogx_bottom_exit)
.show();
要自定义动画文件,可以参考:默认对话框启动动画文件和默认对话框关闭动画文件
额外说明,除了 .setAnimResId(enterAnimResId, exitAnimResId)
外,还有 .setEnterAnimResId(enterAnimResId)
和 .setExitAnimResId(enterAnimResId)
单独方法可选,此方法仅针对单次显示的对话框有效。
另外你也可以通过 setEnterAnimDuration([long])
设置入场动画时长以及通过 .setExitAnimDuration([long])
设置关闭动画时长。
你可以通过静态属性直接修改全局 MessageDialog、InputDialog 的动画:
//设置全局 MessageDialog 入场动画
MessageDialog.overrideEnterAnimRes = R.anim.anim_dialogx_bottom_enter;
//设置全局 MessageDialog 出场动画
MessageDialog.overrideExitAnimRes = R.anim.anim_dialogx_bottom_exit;
//设置全局 MessageDialog 入场动画时间
MessageDialog.overrideEnterDuration = 1000;
//设置全局 MessageDialog 出场动画时间
MessageDialog.overrideExitDuration = 1000;
您还可以通过参考自定义主题接口,完全定制全局的动画框默认动画效果,具体请查阅 《自定义 DialogX 主题》
请注意这三种设置是由优先级区别的,针对单次显示的对话框动画修改优先级 > 对 MessageDialog、InputDialog 全局生效的的动画修改 > 自定义主题修改。
MessageMenu 也是 MessageDialog 的字类,其相关方法与 MessageDialog 一致,类似于 BottomMenu 额外增加了纵向的菜单功能。
直接创建一个简单的菜单弹窗:
private String[] singleSelectMenuText = new String[]{"拒绝", "询问", "始终允许", "仅在使用中允许"};
MessageMenu.show(singleSelectMenuText)
.setMessage("这里是权限确认的文本说明,这是一个演示菜单")
.setTitle("获得权限标题")
.setCancelButton("确定")
你也可以通过以下方法设置菜单:
//设置菜单项目(无级)
.setMenus("添加", "编辑", "删除", "分享"...)
.setMenuList(new String[]{"添加", "编辑", "删除", "分享"})
.setMenuList(List<CharSequence>)
设置菜单回调:
.setOnMenuItemClickListener(new OnMenuItemSelectListener<MessageMenu>() {
@Override
public void onOneItemSelect(MessageMenu dialog, CharSequence text, int index, boolean select) {
selectMenuIndex = index;
}
})
//通过资源直接指定图标
.setIconResIds(R.mipmap.img_dialogx_demo_add, R.mipmap.img_dialogx_demo_delete, R.mipmap.img_dialogx_demo_edit)
//通过回调设置图标
.setOnIconChangeCallBack(new OnIconChangeCallBack<MessageMenu>(true) { //参数代表是否根据亮色/暗色模式对图标染色
@Override
public int getIcon(MessageMenu messageMenu, int index, String menuText) {
switch (menuText) {
case "添加":
return R.mipmap.img_dialogx_demo_add;
case "查看":
return R.mipmap.img_dialogx_demo_view;
case "编辑":
return R.mipmap.img_dialogx_demo_edit;
case "删除":
return R.mipmap.img_dialogx_demo_delete;
}
return 0;
}
})
//通过网络异步加载图标资源
.setOnIconChangeCallBack(new MenuIconAdapter<MessageMenu>(false) { //参数代表是否根据亮色/暗色模式对图标染色
String[] urls = {
"http://www.kongzue.com/test/res/dialogx/ic_menu_add.png",
"http://www.kongzue.com/test/res/dialogx/ic_menu_read_later.png",
"http://www.kongzue.com/test/res/dialogx/ic_menu_link.png"
};
@Override
public boolean applyIcon(MessageMenu dialog, int index, String menuText, ImageView iconImageView) {
Glide.with(MainActivity.this).load(urls[index]).into(iconImageView); //演示通过 Glide 加载网络资源到菜单图标中
return true; //返回值 true 表示该菜单项的图标需要显示,返回 false 该菜单项的图标将隐藏
}
});
//强制重新刷新界面
.refreshUI();
//关闭对话框
.dismiss();
//是否允许点击外部区域或返回键关闭
.setCancelable(boolean);
//设置标题文字样式
.setTitleTextInfo(TextInfo);
//设置消息文字样式
.setMessageTextInfo(TextInfo);
//设置按钮文字样式
.setOkTextInfo(TextInfo);
.setCancelTextInfo(TextInfo);
.setOtherTextInfo(TextInfo);
//设置按钮排列方式,buttonOrientation 可选 LinearLayout.VERTICAL 或 LinearLayout.HORIZONTAL
.setButtonOrientation(buttonOrientation);
//设置返回按键回调
.setOnBackPressedListener(OnBackPressedListener);
//获取对话框实例化对象,您可以通过此方法更深度的定制Dialog的功能
.getDialogImpl()
//获取自定义布局实例
.getCustomView()
//设置背景颜色,强行对对话框背景进行染色,请注意参数为int类型的颜色值而非R.color的索引
.setBackgroundColor(ColorInt);
//InputDialog 是否自动弹出键盘
.setAutoShowInputKeyboard(boolean)
//InputDialog 设置默认输入文本样式
.setInputInfo(InputInfo)
//设置对话框圆角(会裁切内容显示)
.setRadius(float px)
//隐藏对话框(无动画),恢复显示请执行非静态方法的 .show()
.hide();
//隐藏对话框(模拟关闭对话框的动画),恢复显示请执行非静态方法的 .show()
.hideWithExitAnim();
//是否处于显示状态
.isShow()
//设置占位文本
.setInputHintText("Hint Text")
//置顶对话框
.bringToFront()
//指定对话框显示层级
.setThisOrderIndex(int)
MessageDialog 支持修改背景遮罩,这是为了丰富扩展性。如果需要背景遮罩,您可以自行使用如下代码设置:
messageDialog.setMaskColor(colorInt);
请注意,传入参数为 ColorInt 值,您可以使用 Color.parseColor("#4D000000")
设置一个 HEX 色值,或使用 getResources().getColor(R.color.black30)
设置一个颜色的资源值。
TextInfo 用于存储基础文本样式设置,其包含一系列属性和响应的 get/set 方法,例如方法解释如下:
属性 | 解释 | 默认值 |
---|---|---|
fontSize | 字号大小,值为-1时使用默认样式,单位:dp | -1 |
gravity | 对齐方式,值为-1时使用默认样式,取值可使用Gravity.CENTER 等对齐方式 |
-1 |
fontColor | 文字颜色,值为1时使用默认样式,取值可以用Color.rgb(r,g,b)等方式获取 | 1 |
bold | 是否粗体 | false |
请注意,fontColor 为 ColorInt 值,您可以使用 Color.parseColor("#4D000000")
设置一个 HEX 色值,或使用资源 getResources().getColor(R.color.black30)
设置一个颜色的资源值,请勿直接传入资源 ID,它可能会无效。
InputInfo 用于提供输入内容的自定义设置,其包含一系列属性和响应的 get/set 方法,例如方法解释如下:
属性 | 解释 | 默认值 |
---|---|---|
MAX_LENGTH | 最大长度,-1不生效 | -1 |
inputType | 自定义输入类型,类型详见 android.text.InputType | |
textInfo | 默认字体样式 | (TextInfo) |
multipleLines | 是否支持多行 | false |
selectAllText | 默认选中所有文字(便于修改) | false |
cursorColor | 输入框的光标颜色 | |
bottomLineColor | 输入框底线颜色(请注意部分主题下该属性可能影响背景颜色) |
请注意,cursorColor 和 bottomLineColor 为 ColorInt 值,您可以使用 Color.parseColor("#4D000000")
设置一个 HEX 色值,或使用资源 getResources().getColor(R.color.black30)
设置一个颜色的资源值,请勿直接传入资源 ID,它可能会无效。
若你的 App 引入了多种主题,在特定场景下需要使对话框显示为某种非全局的主体样式,可使用 .build()
构建对话框,然后使用 .setStyle(style)
来指定主题样式,在最后执行 .show()
命令显示对话框,例如:
MessageDialog.build()
//或直接使用 .build(IOSStyle.style())
.setStyle(IOSStyle.style())
.setTitle("Title")
.setMessage("Message content.")
.setOkButton("OK")
.show();