很多APP有用到PopWindow,今天来总结一下这个控件
其实这个控件使用痛点就是:如何合理的控制展示位置
如果创建PopupWindow的时候没有指定高宽,那么showAsDropDown默认只会向下弹出显示,这种情况有个最明显的缺点就是:弹窗口可能被屏幕截断,显示不全
showAtLocation这个方法,弹窗坐标是相对于整个屏幕的,所以需要我们自己计算位置,从而更精准的控制窗口展示位置
贴一段关键代码:
/**
* 计算出来的位置,y方向就在anchorView的上面和下面对齐显示,x方向就是与屏幕右边对齐显示
* 如果anchorView的位置有变化,就可以适当自己额外加入偏移来修正
* @param anchorView 呼出window的view (点击弹窗的按钮)
* @param contentView window的内容布局(弹窗布局)
* @return window显示的左上角的xOff,yOff坐标
*/
private static int[] calculatePopWindowPos(final View anchorView, final View contentView) {
final int windowPos[] = new int[2];
final int anchorLoc[] = new int[2];
// 获取锚点View在屏幕上的左上角坐标位置
anchorView.getLocationOnScreen(anchorLoc);
final int anchorHeight = anchorView.getHeight();
// 获取屏幕的高宽
final int screenHeight = ScreenUtils.getScreenHeight(anchorView.getContext());
final int screenWidth = ScreenUtils.getScreenWidth(anchorView.getContext());
contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// 计算contentView的高宽
final int windowHeight = contentView.getMeasuredHeight();
final int windowWidth = contentView.getMeasuredWidth();
// 判断需要向上弹出还是向下弹出显示
final boolean isNeedShowUp = (screenHeight - anchorLoc[1] - anchorHeight < windowHeight);
if (isNeedShowUp) {
windowPos[0] = screenWidth - windowWidth;
windowPos[1] = anchorLoc[1] - windowHeight;
} else {
windowPos[0] = screenWidth - windowWidth;
windowPos[1] = anchorLoc[1] + anchorHeight;
}
return windowPos;
}
注意点:
- 当然这段代码contentView是需要设置宽高,高不能为MATCH_PARENT(不要问为什么,自己试一下就知道了)
如果需要弹下图这种布局样式,则可以动态计算contentView的高度(屏幕高度 - anchorView的顶部padding - anchorView的高度),在此基础上,设置contentView背景为半透明即可
p1.jpg
参考链接:
- https://www.cnblogs.com/popfisher/p/5608436.html (把这个链接内容看完应该差不多了)
PS:时间关系,这篇写的可能让人看起来会吃力点,哪就仔细看下参考链接的内容,很基础扎实
网友评论