如何在Android上水平居中ListPopupWindow/其他视图?

5
我正在创建一个类似于这样的 ListPopupWindow
final ListPopupWindow insidelistPopupWindow = new ListPopupWindow(view.getContext());
insidelistPopupWindow.setContentWidth(getResources().getDimensionPixelSize(R.dimen.popupNewWidth));
insidelistPopupWindow.setHeight(getResources().getDimensionPixelSize(R.dimen.size300dp));
insidelistPopupWindow.setVerticalOffset(getResources().getDimensionPixelSize(R.dimen.size0dp));
insidelistPopupWindow.setHorizontalOffset(getPoupHorizontalOffset());
//set adapter...
insidelistPopupWindow.setAnchorView(view);
insidelistPopupWindow.show();

我试图做简单的数学

public int getPoupHorizontalOffset() {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    int height = displayMetrics.heightPixels;
    int width = displayMetrics.widthPixels;
    return getResources().getDimensionPixelSize(R.dimen.popupNewWidth) - width/2;
}

如何通过编程简单地将某物水平居中?我曾经试过将其在手机上居中,但在其他手机上却没有效果,所以我怀疑我的假设有些问题。我还怀疑有更好的解决方法。

PS:相同的ListPopupWindow但具有不同数量的元素会被放置在屏幕上的不同位置。为什么会这样?

更新:

根据下面的答案,我尝试了

listPopupWindow.setAnchorView(view);

        listPopupWindow.setContentWidth(getResources().getDimensionPixelSize(R.dimen.popupNewWidth));
        listPopupWindow.setHeight(getResources().getDimensionPixelSize(R.dimen.size250dp));
        listPopupWindow.setVerticalOffset(getResources().getDimensionPixelSize(R.dimen.size50dp));
        listPopupWindow.setHorizontalOffset(listPopupWindowWidth(view, listPopupWindow));
        listPopupWindow.setPromptPosition(ListPopupWindow.POSITION_PROMPT_ABOVE);

并且做了

int listPopupWindowWidth(View view, ListPopupWindow listPopupWindow) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int screenWidth = displayMetrics.widthPixels;
        int horizontalOffset = (screenWidth / 2) - (getRelativeLeft(view) + listPopupWindow.getWidth() / 2);
        return horizontalOffset;
    }

private int getRelativeLeft(View view) {
        if (view.getParent() == view.getRootView()) {
            return view.getLeft();
        } else {
            return view.getLeft() + getRelativeLeft((View) view.getParent());
        }
    }

但是我的弹出窗口有点偏左,而不是完全居中。我的视图处于横向模式,这是否与它有关?我尝试通过更改宽度和高度来解决,但没有成功。
1个回答

4
默认情况下,ListPopupWindow 水平对齐于锚定视图的左侧位置。因此,我们应该通过计算当前中心与屏幕中心的差值来将其左侧对齐。
int screenWidth = getScreenSize().x;
if (isLandscape()) {
     screenWidth += getNavigationBarHeight();
}

int horizontalOffset = (screenWidth / 2) - (getRelativeLeft(view) + insidelistPopupWindow.getWidth() / 2);

insidelistPopupWindow.setHorizontalOffset(horizontalOffset);

getRelativeLeft() 帮助我们找到锚定视图相对于屏幕的实际左侧位置(而不是其父级 ViewGroup)。

private int getRelativeLeft(View view) {
    if (view.getParent() == view.getRootView()) {
        return view.getLeft();
    } else {
        return view.getLeft() + getRelativeLeft((View) view.getParent());
    }
}

获取屏幕尺寸的方法:

private Point getScreenSize() {
    Point point = new Point();
    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
    if (wm.getDefaultDisplay() != null) {
        wm.getDefaultDisplay().getSize(point);
    }
    return point;
}

private boolean isLandscape() {
    int orientation = getResources().getConfiguration().orientation;
    return (orientation == Configuration.ORIENTATION_LANDSCAPE);
}

这样,不管锚点视图在水平方向上的位置如何以及它在嵌套布局中的包裹方式是怎样的,ListPopupWindow始终位于屏幕中央。


1
很奇怪!我会检查并回复。 - aminography
1
可以截屏并分享吗? - aminography
1
没错!当你说设备是横屏时,我就是想表达这个意思。 - aminography
1
请查看此链接:https://dev59.com/omIj5IYBdhLWcg3wb0rX#20264361 - aminography
尝试返回宽度而不是高度,但它也显示在左边。 - Guerlando OCs
显示剩余4条评论

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