欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

详解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

 详解Android PopupWindow怎么合理控制弹出位置(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;
  }

接下来调用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截图展示:

详解Android PopupWindow怎么合理控制弹出位置(showAtLocation)

详解Android PopupWindow怎么合理控制弹出位置(showAtLocation)

详解Android PopupWindow怎么合理控制弹出位置(showAtLocation)

demo下载地址:https://github.com/popfisher/smartpopupwindow

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。