0%

PopupWindow弹窗

一,简介

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

致谢:

二、PopupWindow的相关函数

  1. 构造函数

    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)
    1. 要生成一个PopupWindow最基本的三个条件是一定要设置的:contentView,width, height;少任意一个就不可能弹出来PopupWindow

    2. PopupWindow没有默认布局,它不会像AlertDialog那样只setTitle,就能弹出来一个框。PopupWindow是没有默认布局的,它的布局只有通过我们自己设置才行。由于方法三中,含有了这三个必备条件,不用单独设置contentview或者width、height,所以构造方法三是用的最多的一个构造方法。

    3. 如果使用方法一来构造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);
  2. 显示函数

    1. 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)
    2. showAtLocation()显示在一个弹出窗口在指定的位置处的内容图。:

      1
      2
      // 相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移  
      showAtLocation(View parent, int gravity, int x, int y):
    3. 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)
  3. 设置动画效果

    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>
  4. 其它函数

    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)

三、简单实现跟随手指点击

  1. 思路:通过GestureDetector对象识别用户长按事件,获取点击位置相对于屏幕的坐标,使用showAtLocation(rootview, Gravity.NO_GRAVITY, x, y);显示到屏幕上

  2. 关于GestureDetector对象可以看我的另一篇文章View位置及触摸事件

  3. 主要代码(详细内容请查看源码)

    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
    @Override
    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);
    }

    }

    @Override
    public boolean onDown(MotionEvent e) {
    // 这里要设置为true,响应事件,不然点一下屏幕也会显示长按
    return true;
    }

四、项目源码

源码::https://github.com/sdwfqin/AndroidSamples