空祖家的对话框工具V3版,集成三种风格+夜间模式对话框,以及等待、提示、分享等特色对话框,支持花式自定义
请注意,此框架已停止更新,建议尽快切换至 DialogX
迁移文档请参考:从 DialogV3 迁移至 DialogX
献给要求安卓照着苹果设计稿做开发的产品们(手动滑稽
一般情况下直接创建的 Dialog 或 AlertDialog 启动后,一旦其依赖的 Activity 优先于 Dialog 关闭,则会抛出 android.view.WindowLeaked 错误。
这对于普通对话框还好处理,只需要在 Activity 的 onPause() 或 onDestroy() 中对 dialog.dismiss(); 但对于可能出现的,诸如等待提示框、提醒框等 Dialog,很容易发生此问题。
Google 现已推荐使用 DialogFragment 来代替普通 Dialog 使用。
Kongzue Dialog 组件 V3 全部采用 DialogFragment 来实现对话框组件,且创造对话框更为简单方便,只需简单配置即可上手,也不会出现 WindowLeaked 错误。
已知 Android 系统在发生横竖屏切换、分屏大小切换、未来的折叠屏、窗口化等界面大小发生变化的情况时若不进行处理一般都会销毁当前 Activity 重新创建,但这会导致我们已经弹出的 Dialog 也发生重启。
重启最大的麻烦在于需要对重启后的 Dialog 进行原状态恢复,即事件重绑定,包括 Dialog 的样式、相关事件监听器等都需要重新设置,使用 Kongzue Dialog V3 您就不需要再担心这些麻烦的问题,Kongzue Dialog V3 会自动重建被销毁的 Dialog,而无需您做任何处理。
Kongzue Dialog V3 依然会像第二代一样提供多种主题风格选择,且更为强大,iOS 风格自带高斯模糊让您再也无需担心产品经理和设计师放飞自我。
功能强大且真正的实时高斯模糊效果让您的程序更具逼格,同时我们也比苹果更早提供了 iOS 风格对话框夜间模式,若您正在使用暗色的程序设计,这款与您更搭!
我们的组件也会提供许许多多的接口供您自定义对话框的每一点细节,方便而快捷,迅速构建您的程序。
Kongzue Dialog V3 支持模态化窗口模式,启用模态化设置项后,即便从代码一次执行显示多个对话框,实际也会在上一个对话框消失后再显示下一个,以避免对话框叠加造成的混乱情况发生。
另外 Kongzue Dialog 不强制您必须使用 Builder 等方式创建,且为了避免额外的代码量,所有组件均提供了可灵活使用的 show(...) 构造方法,因此只需要输入组件名称,按一下 “.” 按键,即可快速根据提示创建出一个对话框。
下边是 AlertDialog 和 Kongzue Dialog V3 在创建一个典型对话框的代码对比:
使用 AlertDialog:
…使用 Kongzue Dialog V3:
…现已提供 Kongzue Dialog V3 Demo 演示程序供下载体验:
Maven仓库:
com.kongzue.dialog_v3
dialog
3.2.4
pom
Gradle: 在dependencies{}中添加引用:
implementation 'com.kongzue.dialog_v3:dialog:3.2.4'从 Kongzue Dialog V2 升级至 Kongzue Dialog V3,请参考 Kongzue Dialog V2升级注意事项
⚡ 另外提供 AndroidX 版本,源码详见 分支
在dependencies{}中添加引用:
implementation 'com.kongzue.dialog_v3x:dialog:3.2.4' 在完成引入 Kongzue Dialog V3 库后,首先需要进行一些预先配置,诸如对话框组件整体的风格、主题和字体等,它们都可以在一个工具类中进行配置,说明如下:
…如果需要开启模糊效果,即 DialogSettings.isUseBlur = true; 需要进行额外 renderscript 配置,需要注意的是在部分低配置手机上此功能效率可能存在问题。
在 app 的 build.gradle 中添加以下代码:
android {
...
defaultConfig {
...
renderscriptTargetApi 17
renderscriptSupportModeEnabled true
}
}上述配置为全局配置,即在不进行特意定制的情况下,所有对话框组件默认按照此配置显示,如有特殊需求,可以通过各对话框组件的 build(...) 方法创建对话框后进行配置,最后使用 show() 方法执行显示即可。
提供日常消息展示,区分为单按钮、双按钮和三按钮的效果。
以下范例通过参数快速创建一个基本的消息对话框:
MessageDialog.show(MainActivity.this, "提示", "这是一条消息", "确定");额外的,MessageDialog 还提供多种参数的构建方法,方便快速创建合适的对话框:
MessageDialog.show(MainActivity.this, "提示", "这是一条双按钮消息", "确定", "取消");
MessageDialog.show(MainActivity.this, "提示", "这是一条三按钮消息", "确定", "取消", "其他");消息对话框的按钮回调方法提供了一个 return 值用于判断点击按钮后是否需要关闭对话框,默认 return false 会关闭当前的输入对话框,若 return true 则点击该按钮后不会关闭:
MessageDialog.show(MainActivity.this, "更多功能", "点击左边的按钮是无法关掉此对话框的,Kongzue Dialog提供的回调函数可以轻松帮你实现你想要的判断功能", "点我关闭", "我是关不掉的")
.setOnCancelButtonClickListener(new OnDialogButtonClickListener() {
@Override
public boolean onClick(BaseDialog baseDialog, View v) {
return true; //位于“取消”位置的按钮点击后无法关闭对话框
}
});此功能便于做选择判断,在合理的事件触发后可允许关闭对话框。
也可以通过 build(...) 方法创建,并定制更多效果:
MessageDialog.build(MainActivity.this)
.setStyle(DialogSettings.STYLE.STYLE_MATERIAL)
.setTheme(DialogSettings.THEME.DARK)
.setTitle("定制化对话框")
.setMessage("我是内容")
.setOkButton("OK", new OnDialogButtonClickListener() {
@Override
public boolean onClick(View v) {
Toast.makeText(MainActivity.this, "点击了OK!", Toast.LENGTH_SHORT).show();
return false;
}
})
.show();需注意的是,只有修改主题风格的 setStyle(...) 和 setTheme(...) 方法必须在使用 build(...) 创建时才可以修改。
一些特殊需求中可能用到需要纵向排列按钮的三按钮消息框,则可以通过以下方法实现:
MessageDialog
.show(MainActivity.this, "纵向排列", "如果你正在使用iOS风格或Kongzue风格,这里的按钮可以纵向排列,以方便提供更多选择", "还不错", "有点意思", "还有呢?")
.setButtonOrientation(LinearLayout.VERTICAL);额外说明,V3 库支持更灵活的配置按钮方式,除了默认的 setOnOkButtonClickListener(...) 方法以外,你还可以这样写:
…提供额外输入需求的对话框组件,可控制输入内容类型,并在点击按钮时判断是否关闭对话框。
以下范例通过参数快速创建一个基本的输入对话框:
InputDialog.show(MainActivity.this, "输入对话框", "输入一些内容", "确定");InputDialog 与 MessageDialog 类似也提供多种构建方法,在此不再赘述。
输入对话框的按钮回调中会直接返回当前输入的文本内容:
InputDialog.show(MainActivity.this, "提示", "请输入密码", "确定", "取消")
.setOnOkButtonClickListener(new OnInputDialogButtonClickListener() {
@Override
public boolean onClick(BaseDialog baseDialog, View v, String inputStr) {
//inputStr 即当前输入的文本
return false;
}
})如果需要修改输入框的提示语(HintText)或内容(InputText),可以使用以下方法:
InputDialog.show(MainActivity.this, "输入对话框", "输入一些内容", "确定")
.setInputText("123456")
.setHintText("请输入密码")
;如需控制输入内容的字号、颜色、输入长度、文本类型,可以通过以下方法实现:
InputDialog.show(MainActivity.this, "输入对话框", "请输入6位密码", "确定")
.setInputInfo(new InputInfo()
.setMAX_LENGTH(6) //限制最大输入长度
.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD) //仅输入密码类型
.setTextInfo(new TextInfo() //设置文字样式
.setFontColor(Color.RED) //修改文字样式颜色为红色
)
.setMultipleLines(true) //支持多行输入
)
;备注:TextInfo(com.kongzue.dialog.util.TextInfo)类提供了基本的文字样式控制,InputInfo(com.kongzue.dialog.util.InputInfo)类提供了基础的输入文字类型控制。
等待提示对话框提供居中于屏幕阻断操作的等待和状态提示功能。
使用以下代码构建等待对话框:
WaitDialog.show(MainActivity.this, "请稍候...");使用以下代码构建提示对话框:
TipDialog.show(MainActivity.this, "警告提示", TipDialog.TYPE.WARNING);TipDialog 自带三种类型的提示图标(TipDialog.TYPE),可通过参数设置指定:
TipDialog.TYPE.SUCCESS //对勾提示图
TipDialog.TYPE.WARNING //感叹号提示图
TipDialog.TYPE.ERROR //错误叉提示图也可以通过如下代码设置自定义的图片:
TipDialog.show(MainActivity.this, "警告提示", R.mipmap.img_tip); //入参自定义图片资源文件额外的,可以通过以下语句设置 TipDialog 自动关闭的时长(单位:毫秒):
TipDialog.show(MainActivity.this, "成功!", TipDialog.TYPE.SUCCESS)
.setTipTime(5000);如果连续使用,两者会有衔接的效果。
如需手动关闭,执行对应的 dismiss() 方法即可。
需要注意的是,WaitDialog 本质上继承自 TipDialog,它们属于长时间提示功能的组件,且内存中只会创建一次,不会重复创建直到被 dismiss() 关闭,但因为该组件使用 DialogFragment 构建,请勿需担心造成 WindowLeaked 错误问题。
WaitDialog 和 TipDialog 的主题可以通过以下代码自定义:
WaitDialog.show(MainActivity.this, null)
.setTheme(DialogSettings.THEME.LIGHT); //强制指定为亮色模式即从屏幕底部弹出的可选择的菜单。
使用以下代码构建底部菜单:
BottomMenu.show(MainActivity.this, new String[]{"菜单1", "菜单2", "菜单3"}, new OnMenuItemClickListener() {
@Override
public void onClick(String text, int index) {
//返回参数 text 即菜单名称,index 即菜单索引
}
});BottomMenu 可以通过 String[] 集合创建,也可以通过 List 创建。
要为底部菜单加上标题,可以使用以下语句:
BottomMenu.show(MainActivity.this, new String[]{"菜单1", "菜单2", "菜单3"}, new OnMenuItemClickListener() {
@Override
public void onClick(String text, int index) {
log("点击了:" + text);
}
})
.setTitle("这里是标题文字");底部菜单也允许自定义菜单 Adapter 以支持您自己的菜单样式,您可以设置自定义的继承自 BaseAdapter 的菜单 Adapter 给菜单 ListView,此时您无需设置 StringArray 或 List 的集合。
另外请注意,使用自定义菜单 Adapter 的情况下可能导致使用 iOS 风格时无法有效的支持顶部菜单、底部菜单的上下圆角裁切,您可以尝试参考 BottomMenu.IOSMenuArrayAdapter 来编写您的自定义 Adapter。
使用自定义菜单 Adapter 可以使用以下语句:
List datas = new ArrayList<>();
datas.add("菜单1");
datas.add("菜单2");
datas.add("菜单3");
//您自己的Adapter
BaseAdapter baseAdapter = new ArrayAdapter(MainActivity.this, com.kongzue.dialog.R.layout.item_bottom_menu_kongzue, datas);
BottomMenu.show(MainActivity.this, baseAdapter, new OnMenuItemClickListener() {
@Override
public void onClick(String text, int index) {
//注意此处的 text 返回为自定义 Adapter.getItem(position).toString(),如需获取自定义Object,请尝试 datas.get(index)
toast(text);
}
});⚠ 特别说明:
Material 风格的 BottomMenu 默认不支持“取消”按钮,按照设计规范,使用下滑手势关闭。
这里的通知并非系统通知,且不具备在您的设备通知栏中持久显示的特性,它本质上是通过对 Toast 进行修改实现的跨界面屏幕顶部提示条。
不依赖于界面显示,也不会打断用户操作,可作为即时通迅 IM 类软件跨界面消息提醒,或者用于网络错误状态提示。
使用以下代码快速构建通知:
Notification.show(MainActivity.this, "提示", "提示信息");需要加入图标与点击、关闭事件:
Notification.show(MainActivity.this, "提示", "提示信息", R.mipmap.ico_wechat).setOnNotificationClickListener(new OnNotificationClickListener() {
@Override
public void onClick() {
MessageDialog.show(MainActivity.this, "提示", "点击了消息");
}
}).setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
log("消息溜走了");
}
});在 3.2.2 版本以上,由于最 Android 10+ 对自定义 Toast 进行了屏蔽,可能导致部分功能无法正常工作,您可以通过以下方式修改通知的实现方式:
Notification.mode = Notification.Mode.TOAST; //使用自定义 Toast 实现方式
Notification.mode = Notification.Mode.FLOATING_WINDOW; //使用悬浮窗实现方式使用悬浮窗实现方式默认只能够在一个界面显示通知,您可以在 AndroidManifest.xml 增加以下权限声明来开启跨窗口悬浮窗权限:
另附申请开启悬浮窗权限的代码:
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 0);分享对话框会从屏幕底部弹出,并提供图标加文字的选择分享列表。
要使用分享对话框,需要先创建分享 Item:
List itemList = new ArrayList<>();
itemList.add(new ShareDialog.Item(MainActivity.this ,R.mipmap.img_email_ios,"邮件"));
itemList.add(new ShareDialog.Item(MainActivity.this ,R.mipmap.img_qq_ios,"QQ"));
itemList.add(new ShareDialog.Item(MainActivity.this ,R.mipmap.img_wechat_ios,"微信"));
itemList.add(new ShareDialog.Item(MainActivity.this ,R.mipmap.img_weibo_ios,"微博"));
itemList.add(new ShareDialog.Item(MainActivity.this ,R.mipmap.img_memorandum_ios,"添加到“备忘录”"));
itemList.add(new ShareDialog.Item(MainActivity.this ,R.mipmap.img_remind_ios,"提醒事项"));然后创建分享对话框及监听点击事件:
ShareDialog.show(MainActivity.this, itemList, new ShareDialog.OnItemClickListener() {
@Override
public boolean onClick(ShareDialog shareDialog, int index, ShareDialog.Item item) {
toast("点击了:" + item.getText());
return false;
}
});额外需要注意,iOS 风格模式下,默认会自动对图片进行圆角裁切,使用时只需要直接提供方形图标即可。
⚠ 特别说明:
Material 风格的 ShareDialog 默认不支持“取消”按钮,按照设计规范,使用下滑手势关闭。
Kongzue Dialog V3 提供了全屏对话框样式,这种对话框主体采用自定义布局,启动后会占据全屏,可设置标题和标题左右两个按钮。
使用以下代码创建全屏对话框:
…其中第二个参数为自定义的布局资源 id,第三个参数为布局绑定回调,其余方法与其他 Dialog 一致。
额外的,可自定义 FullScreenDialog 的背景颜色:
fullScreenDialog.setBackgroundColor(Color.WHITE);对于任意一个对话框组件,Kongzue Dialog V3 提供了自定义布局功能,您可以使用一下代码来插入自定义布局:
…目前支持自定义子布局的有:消息对话框组件(MessageDialog)、底部菜单组件(BottomMenu)、输入框组件(InputDialog)、分享对话框(ShareDialog)和通知组件(Notification)
Kongzue Dialog V3 提供了完全自定义对话框方便快速实现特殊效果的对话框样式。
使用以下代码创建自定义对话框:
…其他方法
//全屏幕宽高
customDialog.setFullScreen(true);
//设置 CustomDialog 处于屏幕的位置
customDialog.setAlign(CustomDialog.ALIGN.BOTTOM) //从屏幕底端出现
customDialog.setAlign(CustomDialog.ALIGN.TOP) //从屏幕顶端出现
customDialog.setAlign(CustomDialog.ALIGN.DEFAULT) //从屏幕中部出现除 Material 风格外,iOS 和 Kongzue 风格支持自定义 drawable 的方式修改按钮背景(颜色)资源:
您可以通过以下方式全局指定自定义按钮背景资源:
//修改确定按钮背景资源:
DialogSettings.okButtonDrawable = getDrawable(R.drawable.btn_ok);
//其他按钮:
DialogSettings.cancelButtonDrawable = getDrawable(R.drawable.btn_cancel);
DialogSettings.otherButtonDrawable = getDrawable(R.drawable.btn_other);也可以单独指定对话框的按钮背景资源:
//使用资源 id:
messageDialog.setOkButtonDrawable(resId);
//或直接使用 drawable:
messageDialog.setOkButtonDrawable(drawable);drawable资源可按照如下方式设计: btn_ok.xml
其中,dialogButtonBlueLight为默认颜色,dialogButtonBlueLightPress为按下时颜色,请在您的colors.xml资源文件中添加其颜色。
屏幕顶端、底部弹出
//从顶部弹出
Dialog.build(me)
.setAlign(BaseDialog.ALIGN.TOP);
//从底部暂无开放 Issues,或尚未同步最近议题。