setCancelable与setCanceledOnTouchOutside区别:触发取消操作的方式不同。setCancelable() 控制的是对话框是否可以通过按下返回键,而 setCanceledOnTouchOutside() 控制的是当用户点击对话框以外的区域时对话框是否自动取消。
一、setCancelable与setCanceledOnTouchOutside区别
setCancelable(boolean cancelable) 是一个公共方法,可用于设置对话框是否可以通过按下返回键或点击对话框外部来取消。如果设置为 true,则可以通过按下返回键或者调用 DialogInterface.cancel() 方法来关闭对话框;如果设置为 false,则无法通过这些方式关闭对话框。
setCanceledOnTouchOutside(boolean cancel) 则是一个特定于对话框的方法,用于设置当用户点击对话框以外的区域时是否应该自动取消对话框。如果设置为 true,则当用户点击对话框以外的区域时,对话框将自动关闭并调用 DialogInterface.OnCancelListener;如果设置为 false,则对话框将保持打开状态,直到用户显式关闭。
示例:
dialog.setCancelable(false);
dialog弹出后会点击屏幕或物理返回键,dialog不消失。
dialog.setCanceledOnTouchOutside(false);
dialog弹出后会点击屏幕,dialog不消失;点击物理返回键dialog消失。
二、Android 的 Dialog 类
对话框是提示用户作出决定或输入额外信息的小窗口,通常不会填充整个屏幕,用于进行一些额外交互。
Dialog 类是对话框的基类,但应该避免直接实例化 Dialog,而应使用其子类,比如:
- AlertDialog:此对话框可显示标题、提示信息、按钮、可选择项列表或自定义布局等
- DatePickerDialog 或 TimePickerDialog:此类对话框带有允许用户选择日期或时间的预定义 UI
1、基础用法
通过扩展 DialogFragment 类并在 onCreateDialog() 回调方法中创建 AlertDialog:
public class MyDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle("title") .setMessage("message") .setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { } }); return builder.create(); } }
之后,当创建此类的实例并调用该对象上的 show() 方法时,就可以显示出对话框了。
2、包含两个按钮的对话框
在 ButtonDialogFragment 类中重载 show() 方法,传入所有需要的参数,并调用 DialogFragment 类本身的 show(FragmentManager manager, String tag) 方法,从而显示对话框。“tag” 参数是系统用于保存片段状态并在必要时进行恢复的少数标记名称,该标记还允许通过调用 findFragmentByTag() 获取片段的句柄:
/** * Created by 叶应是叶 on 2017/2/23. */public class ButtonDialogFragment extends DialogFragment { private DialogInterface.OnClickListener positiveCallback; private DialogInterface.OnClickListener negativeCallback; private String title; private String message; public void show(String title, String message, DialogInterface.OnClickListener positiveCallback, DialogInterface.OnClickListener negativeCallback, FragmentManager fragmentManager) { this.title = title; this.message = message; this.positiveCallback = positiveCallback; this.negativeCallback = negativeCallback; show(fragmentManager, "ButtonDialogFragment"); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(title); builder.setMessage(message); builder.setPositiveButton("确定", positiveCallback); builder.setNegativeButton("取消", negativeCallback); return builder.create(); }}
之后,提供调用方法:
public void showButtonDialogFragment(View view) { ButtonDialogFragment buttonDialogFragment = new ButtonDialogFragment(); buttonDialogFragment.show("Hi,你好", "叶应是叶", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "点击了确定 " + which, Toast.LENGTH_SHORT).show(); } }, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "点击了取消 " + which, Toast.LENGTH_SHORT).show(); } }, getFragmentManager()); }
3、包含一个中性按钮的对话框
思路类似,对话框包含一个中性按钮:
/** * Created by ZY on 2017/2/23. */public class NeutralDialogFragment extends DialogFragment { private DialogInterface.OnClickListener neutralCallback; private String title; private String message; private String hint; public void show(String title, String message, String hint, DialogInterface.OnClickListener neutralCallback, FragmentManager fragmentManager) { this.title = title; this.message = message; this.hint = hint; this.neutralCallback = neutralCallback; show(fragmentManager, "NeutralDialogFragment"); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(title); builder.setMessage(message); builder.setNeutralButton(hint, neutralCallback); return builder.create(); }}
提供调用方法:
public void showNeutralDialogFragment(View view) { NeutralDialogFragment neutralDialogFragment = new NeutralDialogFragment(); neutralDialogFragment.show("Hi,你好", "叶应是叶", "确定~", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "点击了按钮 " + which, Toast.LENGTH_SHORT).show(); } }, getFragmentManager()); }
延伸阅读1:创建 DialogFragment 的两种方式
Android 官方推荐使用 DialogFragment 来代替 Dialog ,可以让它具有更高的可复用性(降低耦合)和更好的便利性(很好的处理屏幕翻转的情况)。而创建 DialogFragment 有两种方式:
- 覆写其 onCreateDialog 方法:一般用于创建替代传统的 Dialog 对话框的场景,UI 简单,功能单一,不适用于使用了多线程(例如网络请求)的情况下(因为不能正确的获取当前 Fragment 的状态,会产生空指针异常)。
- 覆写其 onCreateView 方法:一般用于创建复杂内容弹窗或全屏展示效果的场景,UI 复杂,功能复杂,一般有网络请求等异步操作。