一,简介
PopupWindow这个类用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的。

致谢:
- PopUpWindow使用详解(一)——基本使用:http://blog.csdn.net/harvic880925/article/details/49272285
- PopUpWindow使用详解(二)——进阶及答疑:http://blog.csdn.net/harvic880925/article/details/49278705
二、PopupWindow的相关函数
- 构造函数 - 1 
 2
 3
 4
 5
 6
 7
 8- // 方法一: 
 public PopupWindow (Context context)
 // 方法二:
 public PopupWindow(View contentView)
 // 方法三:
 public PopupWindow(View contentView, int width, int height)
 // 方法四:
 public PopupWindow(View contentView, int width, int height, boolean focusable)- 要生成一个PopupWindow最基本的三个条件是一定要设置的:contentView,width, height;少任意一个就不可能弹出来PopupWindow 
- PopupWindow没有默认布局,它不会像AlertDialog那样只setTitle,就能弹出来一个框。PopupWindow是没有默认布局的,它的布局只有通过我们自己设置才行。由于方法三中,含有了这三个必备条件,不用单独设置contentview或者width、height,所以构造方法三是用的最多的一个构造方法。 
- 如果使用方法一来构造PopupWindow,那完整的构造代码应该是这样的: - 1 
 2
 3
 4
 5- View contentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.popuplayout, null); 
 PopupWindow popWnd = PopupWindow (context);
 popWnd.setContentView(contentView);
 popWnd.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
 popWnd.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
 
- 显示函数 - showAsDropDown()显示在一个参照物View的周围,有三个方法重载: - 1 
 2
 3
 4
 5
 6- // 相对某个控件的位置(正左下方),无偏移 
 showAsDropDown(View anchor)
 // 相对某个控件的位置,有偏移;xoff表示x轴的偏移,正值表示向左,负值表示向右;yoff表示相对y轴的偏移,正值是向下,负值是向上;
 showAsDropDown(View anchor, int xoff, int yoff)
 // 显示挂靠到其他视图的角落弹出窗口中的内容视图。
 showAsDropDown(View anchor, int xoff, int yoff, int gravity)
- showAtLocation()显示在一个弹出窗口在指定的位置处的内容图。: - 1 
 2- // 相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移 
 showAtLocation(View parent, int gravity, int x, int y):
- update()更新位置和弹出窗口的尺寸,有六个方法重载。 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- // 更新位置和弹出窗口的尺寸。 
 update(View anchor, int width, int height)
 // 更新位置和弹出窗口的尺寸。
 update(View anchor, int xoff, int yoff, int width, int height)
 // 更新弹出窗口的尺寸。
 update(int width, int height)
 // 更新弹出窗口的状态下,如果当前正在显示它,从当前设置的状态。
 update()
 // 更新位置和弹出窗口的尺寸。
 update(int x, int y, int width, int height, boolean force)
 // 更新位置和弹出窗口的尺寸。
 update(int x, int y, int width, int height)
 
- 设置动画效果 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11- // 在Android的所有版本,弹出窗口进入和退出动画可以通过调用来指定样式, 
 // 并传递资源ID定义动画风格windowEnterAnimation和windowExitAnimation。
 public void setAnimationStyle(int animationStyle)
 // 样式文件(Style)
 <style name="contextMenuAnim" parent="@android:style/Animation.Activity">
 <!--进入-->
 <item name="android:windowEnterAnimation">@anim/menu_enter</item>
 <!--退出-->
 <item name="android:windowExitAnimation">@anim/menu_exit</item>
 </style>
- 其它函数 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19- // 判断是否弹出 
 public boolean isShowing()
 // 取消弹窗
 public void dismiss()
 // PopupWindow是否具有获取焦点的能力,默认为False。
 // 如果为False,下面的返回关闭PopupWindow可能无效
 // 如果不能获取焦点,那么EditText将无法编辑的。
 public void setFocusable(boolean focusable)
 // 设置PopupWindow是否响应touch事件,默认是true,
 // 如果设置为false,即会是所有touch事件无响应,包括点击事件
 public void setTouchable(boolean touchable)
 // PopupWindow以外的区域是否可点击,
 // 点击PopupWindow以外的区域,PopupWindow是否会消失。(需要配合如果不加setBackgroundDrawable())
 public void setOutsideTouchable(boolean touchable)
 // 设置背景;加上setOutsideTouchable()才会生效;
 // 只有加上它之后,PopupWindow才会对手机的返回按钮有响应:
 // 即点击手机返回按钮,可以关闭PopupWindow;
 // 如果不加setBackgroundDrawable()将关闭的PopupWindow所在的Activity。
 public void setBackgroundDrawable(Drawable background)
三、简单实现跟随手指点击
- 思路:通过GestureDetector对象识别用户长按事件,获取点击位置相对于屏幕的坐标,使用 - showAtLocation(rootview, Gravity.NO_GRAVITY, x, y);显示到屏幕上
- 关于GestureDetector对象可以看我的另一篇文章View位置及触摸事件 
- 主要代码(详细内容请查看源码) - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 public void onLongPress(MotionEvent e) {
 Log.e(TAG, "onShowPress: " + "长按");
 // 获取点击位置相对于屏幕的坐标
 int x = (int) e.getRawX();
 int y = (int) e.getRawY();
 x -= Utils.dp2px(LongShowPopupActivity.this, 55);
 if (mPopWindow != null) {
 if (mPopWindow.isShowing()) {
 mPopWindow.dismiss();
 showPopupWindow(x, y);
 } else {
 showPopupWindow(x, y);
 }
 } else {
 showPopupWindow(x, y);
 }
 }
 public boolean onDown(MotionEvent e) {
 // 这里要设置为true,响应事件,不然点一下屏幕也会显示长按
 return true;
 }