如何在特定位置显示PopupWindow?

33

我需要在屏幕上显示一个View下方的弹出窗口PopupWindow

我该如何计算所需View的坐标并将PopupWindow放置在其下方?代码示例更加受欢迎。谢谢。

3个回答

122

定位已经显示的视图非常容易-这是我在代码中使用的方法:

public static Rect locateView(View v)
{
    int[] loc_int = new int[2];
    if (v == null) return null;
    try
    {
        v.getLocationOnScreen(loc_int);
    } catch (NullPointerException npe)
    {
        //Happens when the view doesn't exist on screen anymore.
        return null;
    }
    Rect location = new Rect();
    location.left = loc_int[0];
    location.top = loc_int[1];
    location.right = location.left + v.getWidth();
    location.bottom = location.top + v.getHeight();
    return location;
}

您可以使用类似Ernesta建议的代码将弹出窗口固定在相关位置:

popup.showAtLocation(parent, Gravity.TOP|Gravity.LEFT, location.left, location.bottom);

这将直接在原视图下方显示弹出窗口 - 不能保证有足够的空间来显示视图。

2
这段代码真棒,非常有用!很抱歉我不能做更多的贡献 ;) - S.Thiongane
+1 只需要添加一些东西,首先最好只使用Gravity.NO_GRAVITY,然后如果您想要有一个边距,以便弹出窗口不会在边缘上,您可以减去(例如location.left - 50)。请记住,在使用location.right时,您需要测量弹出窗口的宽度。有关弹出窗口测量,请转到此处https://dev59.com/IGUo5IYBdhLWcg3wpg_N。带边距的窗口的最终代码:location.left - popUpWindowWidth - 50 - Kim Montano
1
这个解决方案适用于RTL布局吗?如果不是,需要做哪些修改才能使其与从右到左的配置一起工作? - A.B.
@zeetoobiker,你的解决方案完美地运作了!但是我在弹出窗口中使用SwitcherView。所以在切换视图后,它会改变弹出窗口的位置。有什么想法吗? - GreenROBO
@zeetoobiker,这对我不起作用,因为我有一个位于嵌套线性布局中的文本视图。有人有关于此的建议吗? - Irfan Yaqub
显示剩余2条评论

8
您可以使用getLeft()getBottom()方法获取视图在布局中的确切位置。您还可以使用getWidth()getHeight()方法了解视图占用的确切空间。如果您想将弹出窗口定位在视图下方。

您可以使用setLeft()setTop()方法来定位新的弹出窗口。


你能给出任何例子吗? - Vijay E

2

要获取主应用程序屏幕的大小,不包括标题和通知栏等内容,请在生成相关屏幕的类中覆盖以下方法(尺寸以像素为单位测量):

@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int height = MeasureSpec.getSize(heightMeasureSpec);
}

要获取弹出窗口下方视图的底部坐标,请执行以下操作:
View upperView = ...
int coordinate = upperView.getBottom();

只要高度 - 坐标对于您的弹出视图足够大,您就可以像这样放置弹出窗口:

PopupWindow popup = new PopupWindow();

Button button = new Button(this);
button.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        popup.showAtLocation(parent, Gravity.CENTER, 0, coordinate);
    }
});

在这里,showAtLocation()方法需要父视图作为参数,还需要提供相对于父视图的重心和偏移位置。


只有当“button”位于屏幕中央时,此方法才有效。即使我手动设置了“offset”,在不同的屏幕尺寸上也无法正常工作。 - Eugene
“按钮”可以放置在任何地方。 - Eugene
等等 - 所以我提出的解决方案是在您的按钮下方显示弹出窗口。如果您将按钮放得更低,弹出窗口也会出现在更低的位置。而且,由于我想象中的弹出窗口占据了整个屏幕的宽度,所以按钮是否水平居中并不重要。或者我在这里漏掉了什么吗? - user519908
不错,View.getBottom()。但是代码中有一个小问题。我已经在编辑部分添加了修改。 - Shaista Naaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接