详解Android PopupWindow怎么合理控制弹出位置(showAtLocation)
程序员文章站
2023-12-09 20:56:28
说到popupwindow,应该都会有种熟悉的感觉,使用起来也很简单
// 一个自定义的布局,作为显示的内容
context context = null; ...
说到popupwindow,应该都会有种熟悉的感觉,使用起来也很简单
// 一个自定义的布局,作为显示的内容 context context = null; // 真实环境中要赋值 int layoutid = 0; // 布局id view contentview = layoutinflater.from(context).inflate(layoutid, null); final popupwindow popupwindow = new popupwindow(contentview, layoutparams.wrap_content, layoutparams.wrap_content, true); popupwindow.settouchable(true); // 如果不设置popupwindow的背景,有些版本就会出现一个问题:无论是点击外部区域还是back键都无法dismiss弹框 // 这里单独写一篇文章来分析 popupwindow.setbackgrounddrawable(new colordrawable()); // 设置好参数之后再show popupwindow.showasdropdown(contentview);
如果创建popupwindow的时候没有指定高宽,那么showasdropdown默认只会向下弹出显示,这种情况有个最明显的缺点就是:弹窗口可能被屏幕截断,显示不全,所以需要使用到另外一个方法showatlocation,这个的坐标是相对于整个屏幕的,所以需要我们自己计算位置。
如下图所示,我们可以根据屏幕左上角的坐标a,屏幕高宽,点击view的左上角的坐标c,点击view的大小以及popupwindow布局的大小计算出popupwindow的显示位置b
计算方法源码如下:
/** * 计算出来的位置,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; }
接下来调用showatloaction显示:
view windowcontentviewroot = 我们要设置给popupwindow进行显示的view int windowpos[] = calculatepopwindowpos(view, windowcontentviewroot); int xoff = 20;// 可以自己调整偏移 windowpos[0] -= xoff; popupwindow.showatlocation(view, gravity.top | gravity.start, windowpos[0], windowpos[1]); // windowcontentviewroot是根布局view
上面的例子只是提供了一种计算方式,在实际开发中可以根据需求自己计算,比如anchorview在左边的情况,在中间的情况,可以根据实际需求写一个弹出位置能够自适应的popupwindow。
补充上获取屏幕高宽的代码screenutils.java:
/** * 获取屏幕高度(px) */ public static int getscreenheight(context context) { return context.getresources().getdisplaymetrics().heightpixels; } /** * 获取屏幕宽度(px) */ public static int getscreenwidth(context context) { return context.getresources().getdisplaymetrics().widthpixels; }
demo截图展示:
demo下载地址:https://github.com/popfisher/smartpopupwindow
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。