对话框:阻塞式PopupWindow 和非阻塞AlertDialog

来源:互联网 发布:广西广电网络招聘 编辑:程序博客网 时间:2024/04/29 10:57
PopupWindow 弹出对话框的一种,和AlertDialog类似,可以用来实现一个悬浮的菜单
API定义:A popup window that can be used to display an arbitrary view. The popup window is a floating container that appears on top of the current activity.

AlertDialog和Popupwindow的区别:

1)Popupwindow可以全屏,而且可以控制显示在屏幕的位置,这些都是AlertDialog无法做到的

2)AlertDialog是非阻塞线程的,Popupwindow是阻塞线程的。

关于Popupwindow阻塞线程,写这篇文章之前,我参考了很多朋友的日志,再和自己的程序运行结果对比,发现差异挺大,以下就把自己的结论贴出来,欢迎大家指出错误。

这个是我的界面,每个按钮分别对应不同的弹出对话框,


[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 显示AlertDialog对话框: 
  3.  *  
  4.  * @see AlertDialog是非阻塞式对话框,可以再oncreate方法中直接调用显示 
  5.  *      :AlertDialog弹出时,点击对话框之外背景,对话框消失,程序不仅响应AlertDialog的操作 
  6.  *      ,还响应其他操作 
  7.  */  
  8. private void showDialog() {  
  9.     AlertDialog.Builder builder = new AlertDialog.Builder(context);  
  10.     builder.setTitle("标题");  
  11.     builder.setMessage("AlertDialog对话显示的内容");  
  12.     // 注意,Dialog内容可以用自定义布局填充  
  13.     // builder.setView(view);  
  14.     builder.setPositiveButton("确定"new Dialog.OnClickListener() {  
  15.         @Override  
  16.         public void onClick(DialogInterface dialog, int which) {  
  17.             // TODO  
  18.         }  
  19.     }).setNegativeButton("取消"new Dialog.OnClickListener() {  
  20.         @Override  
  21.         public void onClick(DialogInterface dialog, int which) {  
  22.             dialog.dismiss();  
  23.         }  
  24.     });  
  25.     // 创建对话框  
  26.     AlertDialog dialog = builder.create();  
  27.     dialog.show();  
  28. }  

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 显示PopupWiodow对话框 
  3.  *  
  4.  * @see PopupWindow是阻塞式对话框,PopupWindow弹出时 
  5.  *      ,背景没有什么变化,但是当我们点击背景的时候,PopupWindow不会消失,但是PopupWindow对话框之外的按钮依然可以点击。 
  6.  *      Popupwindow可以全屏,而且可以控制显示在屏幕的位置,这些都是AlertDialog无法做到的。 
  7.  */  
  8. private void showPopupWindow() {  
  9.     LayoutInflater inflater = LayoutInflater.from(context);  
  10.     // 加载指定布局作为PopupWindow的显示内容  
  11.     View contentView = inflater.inflate(R.layout.item_popup, null);  
  12.     popupWindow = new PopupWindow(contentView, LayoutParams.MATCH_PARENT,  
  13.             LayoutParams.WRAP_CONTENT);  
  14.     // setPopFoucus();  
  15.     popupWindow.showAtLocation(btnDialog, Gravity.BOTTOM, 00);  
  16.     popupWindow.showAsDropDown(btnDialog);  
  17. }  
如下图:单我点击按钮在指定位置弹出PopupWindow时,再点击PopupWindow之外的按钮,依然能得到响应(弹出土司提示信息,)
甚至在弹出PopupWindow的基础上依然可以点击第一个按钮,依然获得响应可以弹出AlertDialog


关于线程阻塞,在oncrete方法中调用直接调用显示PopupWindow时会报出异常

java.lang.RuntimeException: Unable to start activity 

Android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

由于PopupWindow是依附于Activity之上,当Activity还未创建完成,所以显示PopupWindow时就发生异常
所以 PopupWindow必须在某个事件中显示或者是开启一个新线程去调用,不能直接在onCreate方法中显示

AlertDialog弹出时,点击对话框之外背景,对话框消失,而默认的PopupWindow却没有效果,所以需要加上以下几行代码
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. // 设置popupWindow获得焦点  
  2. popupWindow.setTouchable(true);  
  3. // 设置popupWindow以外的区域可点击,点击后空白处,对话框消失  
  4. popupWindow.setOutsideTouchable(true);  
  5. popupWindow.setBackgroundDrawable(new BitmapDrawable(getResources(),  
  6.         (Bitmap) null));  

PopupWindow的显示及位置设置

window.showAtLocation(parent, Gravity.RIGHT | Gravity.BOTTOM10,10);
第一个参数指定PopupWindow的锚点view,即依附在哪个view上。
第二个参数指定起始点为parent的右下角,第三个参数设置以parent的右下角为原点,向左、上各偏移10像素。
//将PopupWindow作为anchor的下拉窗口显示。即在anchor的左下角显示
window.showAsDropDown(anchor);
//xoff,yoff基于anchor的左下角进行偏移。
window.showAsDropDown(anchor, xoff, yoff);



全屏的PopupWindow
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 弹出全屏对话框 
  3.  */  
  4. private void showPopupFullWindow() {  
  5.     // 获得LayoutInflater的另外一种方式  
  6.     LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  7.     // 加载指定布局作为PopupWindow的显示内容  
  8.     View contentView = inflater.inflate(R.layout.item_popup, null);  
  9.   
  10.     // 注意:popup的全屏是不包括顶部状态栏高度,所以 popup的真正高度是屏幕高度减去状态栏高度,否则会部分显示在外  
  11.     int mScreenWidth = getWindowManager().getDefaultDisplay().getWidth();  
  12.     int mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();  
  13.     Rect rect = new Rect();  
  14.     this.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);  
  15.     int statusBarHeight = rect.top; // 状态栏高度  
  16.     int realHeight = mScreenHeight - statusBarHeight;  
  17.   
  18.     // 初始化popupWindow,指定显示内容和宽高  
  19.     popupWindow = new PopupWindow(contentView, mScreenWidth, realHeight);  
  20.     setPopFoucus();  
  21.     popupWindow.showAtLocation(btnDialog, Gravity.BOTTOM, 00);  
  22.     popupWindow.showAsDropDown(btnDialog);  

0 0
原创粉丝点击