Android PopupWindow的显示位置说明

Android PopupWindow的显示位置说明

位置

  • PopupWindow最关键的就是要让窗体显示在合适的位置,而设置位置的有两个方法,一个是showAtLocation,一个是showAsDropDown
 public void showAtLocation(View parent, int gravity, int x, int y)
 public void showAsDropDown(View anchor, int xoff, int yoff)

showAsDropDown

  • 其中showAtLocation是相对于整个窗体来说的,而showAsDropDown则是以第一个参数的view作为锚点,通过xoff,yoff偏移量来控制PopupWindow的绘制起点

  • 在这里插入图片描述

  • 如上图,比如我们想让PopupWindow显示在某个view(我们称之为anchor)的正上方,那么我们先要知道anchor这个view的左下角(注意是左下角)的坐标,然后根据PopupWindow要显示的位置计算PopupWindow的左上角的坐标,这两个坐标的差值就是xoff,yoff的值了

  • 例如你已经知道anchor的左下角坐标为(100,100),而PopupWindow的左上角坐标为(80,50),那么xoff = 80 - 100= -20,yoff = 50 - 100 = -50

  • 因此我们只要在同个坐标系下得到anchor的左下角坐标和popupwindow的左上角坐标,则xoff和yoff即为popupwindow减去anchor的差值

if (show) {
            if (bottomMembersPopupWindow != null && bottomMembersPopupWindow.isShowing()) {
                return;
            }
            LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View vPopupWindow = inflater.inflate(R.layout.popup_hint, null, false);//引入弹窗布局
            bottomMembersPopupWindow = new PopupWindow(vPopupWindow, ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, true);
            bottomMembersPopupWindow.setAnimationStyle(-1);//默认动画
            bottomMembersPopupWindow.setOutsideTouchable(true);
            vPopupWindow.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
            int yDelay = -5;//y方向偏移,负数表示向上偏移
            bottomMembersPopupWindow.showAsDropDown(ivMembers, -(vPopupWindow.getMeasuredWidth() - ivMembers.getMeasuredWidth()) / 2, -(vPopupWindow.getMeasuredHeight() + ivMembers.getMeasuredHeight()) + yDelay);
        } else {
            if (bottomMembersPopupWindow != null) {
                bottomMembersPopupWindow.dismiss();
            }

        }

showAtLocation

 public void showAtLocation(View parent, int gravity, int x, int y);
  • 参数parent是能拿到getWindowToken()的view即可,因此只要是当前继承View的任何子类都可以,可以是TextView,ImageView,RelativeLayout等,很多人一看到parent都会想当然以为是ViewGroup类型的才可以,其实不然,它只是为了确定是哪个窗体而已
  • gravity则是指示窗体坐标原点在哪里,默认android是以窗体左上角为原点,也就是NO_GRAVITY
  • Gravity.NO_GRAVITY其实等同于Gravity.LEFT | Gravity.TOP,都表示左上角,那么相对的Gravity.RIGHT | Gravity.TOP就表示以右上角为原点了,Gravity.LEFT 就是以(0,窗体高度一半)为原点,其他以此类推
  • 不过我们一般使用的就是Gravity.NO_GRAVITYGravity.CENTER,即以左上角为原点或以窗体中心点为原点
  • 接下来的x和y参数其实就依赖gravity参数选择的参考系了,然后(x,y)就是在选定的gravity的参考系中的坐标,一般情况下建议你使用Gravity.NO_GRAVITY,这样就跟android的左上角为原点的参考系一样了,易于理解且不容易出错
  • 最后,不管怎样,即使你的x,y坐标实际上已经超出了窗体,showAtLocation也会把它显示在窗体内
  • 如果想超出窗体,那么就得设置PopupWindow.setClippingEnabled(false),为false就可以超出窗体了,不过超出窗体那部分是不可见的

其他

  • 如果想在popupwindow显示后更改位置,则可以调用update接口,重复调用showAtLocation和showAsDropDown是不会更新位置的,因为内部判断正在显示的话就返回不会往下执行了
  • 在调用showAsDropDown时在边界地带会发现内容被挤压截断,此时只需要再次调用update接口即可

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值