相信PopupWindow 都用的很熟练了,一开始自己是不喜欢用PopupWindow的,比较喜欢用 DialogFragment这种弹窗,因为位置好控制(后面会写一篇关于DialogFragment的使用记录),但是DialogFragment的弹窗有自己的局限,就是弹窗的位置只有系统提供的那几种,灵活度不够,相反PopupWindow 对于弹窗位置的控制就比较灵活了,还是先来一张效果图:
关于弹窗的动画可以参考Android 补间动画 scale(缩放)
都知道PopupWindow显示的方法有三个:
1、showAsDropDown(anchor),以触发弹出窗的view为基准,出现在view的正下方,弹出的pop_view左上角正对view的左下角 偏移量默认为0,0
2、showAsDropDown(anchor, xoff, yoff),以触发弹出窗的view为基准,以view的左下角进行偏移
3、showAtLocation(parent, gravity, x, y),
第一个参数是View类型的parent,虽然这里参数名是parent,其实,不是把PopupWindow放到这个parent里,并不要求这个parent是一个ViewGroup,这个参数名让人误解。
官方文档"a parent view to get theandroid.view.View.getWindowToken() token from",这个parent的作用应该是调用其getWindowToken()方法获取窗口的Token,所以,只要是该窗口上的控件就可以了。
第二个参数是Gravity,可以使用|附加多个属性,如Gravity.LEFT|Gravity.BOTTOM。
第三四个参数是x,y偏移。
总结一下:前两个showAsDropDown方法是让PopupWindow相对于某个控件显示;而showAtLocation是相对于整个窗口的。
以上是关于三个显示PopupWindow的方法的解释,相信有许多博客都有介绍,这里就简单的提一下吧。
相信只要用心看了上面关于三个方法的解释,应该都懂了,这里要着重说明一点:PopupWindow 的左上角坐标,对应我们设置的 偏移量,因此设置PopupWindow的显示位置,重点在于确定(或者计算)偏移量
像开篇的效果图中:“向左弹出” PopupWindow
从这个效果图可以看出:
1、PopupWindow的高度 小于按钮的高度,而且PopupWindow的上边距离按钮的上边间距 等于 PopupWindow的下边距离按钮的下边间距;
2、PopupWindow的右边距离按钮的左边有一点间隔。
下面分别用两种方式实现这个效果:(申明 这里的popupWindow:就是我们创建的popupWindow对象,view:就是我们点击显示 popupWindow的按钮;)
1、showAsDropDown(anchor, xoff, yoff)方式:直接上代码截图看的清楚一些
那么这里的变量b表示什么意思呢?
使用三目运算符 获取PopupWindow 和 点击的按钮的 高度 差的一半值;(还有其他的方式获取就自行脑补吧 ^_^,比如 绝对值的方式)
剩下的就是要计算偏移量了,首先计算x坐标上的偏移量:因为popupWindow 在 按钮的左边,所以x 偏移量为负 ,偏移popupWindow的宽度,
根据要求,popupWindow和按钮之间有一点间距 所以这里 加 8 (单位是px),最终x的偏移量表达式为 -(popupWindow.getWidth() +8);
接下来就是 y坐标上的偏移量:因为 showAsDropDown(anchor, xoff, yoff)方法偏移是以控件的左下角为基准进行偏移,而根据最终popupWindow显示效果可知
y偏移量为负,偏移popupWindow 的高度 加 b (PopupWindow 和 点击的按钮的 高度 差的一半值)。
2、showAtLocation(parent, gravity, x, y)方式:还是先附上代码截图
其实这两种显示popupWindow 的方式,关键点都是在于确定(或者计算)偏移量 ,区别在于 方式一是以控件的左下角基准, 方式二是以控件的左上角为基准;
简单的做一下方式二的解释,首先获取按钮 左上角的坐标(相对于整个屏幕的坐标);
第一个参数:findViewById(android.R.id.content) 表示获取布局中的一个View,相信使用过 Android 自带的布局分析工具HierarchyView 的都知道这个ID,
(不熟悉可以看这里按步骤操作一下);
第二个参数:Gravity.NO_GRAVITY 看名字大概可以猜出是表示 不设置弹窗相对于整个屏幕的位置,换句话说就是弹窗的位置完全根据后面两个参数决定;
第三个参数:x 坐标上的偏移量,
第四个参数:y 坐标上的偏移量,
关于偏移量的计算,就不多做解释了,和方式一是类似的,只要确定以那一个坐标点为基准即可(以上理解如有不对的地方欢迎给予指正,不胜感激^_^)