Dialog 和 PopupWindow 在开发中是比较常用的两个 View,二者都需要在 Window 上显示出来,正所谓有 View 的地方就有 Window,同时二者都需要调用 setContentView 方法,具体原理请查看文章(https://blog.csdn.net/xgangzai/article/details/81390630)
Dialog 与 PopupWindow 的区别
- 系统 Dialog 可以通过非界面组件启动
- 二者可以手动设置显示位置。Dialog 默认居中 Gravity.CENTER,PopupWindow 默认在左上角显示
- PopupWindow 在显示之前一定要设置宽高,Dialog 没有特殊限制,可以不设置
- PopupWindow 默认不会响应物理键盘的返回键,除非设置了 focusable = true;点击返回键时 Dialog 会消失,也可以通过设置让 Dialog 不响应返回键
-
@Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && this.isShowing()) { // this.dismiss(); return true; } return false; }
- Dialog 在显示的时候,默认会添加蒙层,PopupWindow 不添加蒙层,可以在 style 设置中去掉 Dialog 的蒙层
-
<item name="android:windowBackground">@android:color/transparent</item> <item name="android:background">@android:color/transparent</item>
-
当 PopupWindow 和 Dialog 显示之后,默认情况下,点击页面其它部分,PopupWindow 是不会关闭的,但是 Dialog 默认会关闭掉
-
popupWindow.setOnTouchListener(this); //点击外部 PopupWindow 消失 @Override public boolean onTouch(View v, MotionEvent event) { int height = rootView.findViewById(R.id.linearlayout_window).getTop(); int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_UP) { if (y < height) { dismiss(); } } return true; } // 设置 Dialog 点击页面其它部分不可以关掉 mDialogbind.setCanceledOnTouchOutside(false);
-
Dialog 和 PopupWindow 都有默认的背景,都可以直接通过 setBackgroundDrawable 去掉,也可以直接在style中设置去掉背景
-
Dialog 默认带有标题,PopupWindow 没有标题。可以通过 Dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) 取消标题
-
AlertDialog 是非阻塞式对话框:AlertDialog 弹出时,后台还可以做事情;而 PopupWindow 是阻塞式对话框,PopupWindow弹出时,程序会等待,在 PopupWindow 退出前,程序一直等待,只有当我们调用了 dismiss 方法的后,PopupWindow 退出,程序才会向下执行。这两种区别的表现是:AlertDialog 弹出时,背景是黑色的,但是当我们点击背景,AlertDialog 会消失,证明程序不仅响应 AlertDialog 的操作,还响应其他操作,其他程序没有被阻塞,这说明了 AlertDialog 是非阻塞式对话框;PopupWindow 弹出时,背景没有什么变化,但是当我们点击背景的时候,程序没有响应,只允许我们操作 PopupWindow,其他操作被阻塞
开发过程中如何选择二者
- 对于不需要背景的弹出框可以选择 PopupWindow,如果背景需要灰色半透明,可以使用 Dialog
- 需要指定位置时候可以直接选择 PopupWindow
- 显示框后面的内容是否需要阻塞来选择弹出框