如何水平居中 Android 上的 ListPopupWindow/Other 视图?

Gue*_*OCs 5 java android android-layout

我正在创建一个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();
Run Code Online (Sandbox Code Playgroud)

我试着做简单的数学

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;
}
Run Code Online (Sandbox Code Playgroud)

使其水平居中。它适用于我的手机,但不适用于其他人,所以我怀疑我的假设有问题。但我也怀疑有更好的方法来解决这个问题。

我如何简单地以编程方式水平居中?

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);
Run Code Online (Sandbox Code Playgroud)

并且做了

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());
        }
    }
Run Code Online (Sandbox Code Playgroud)

但我的弹出窗口稍微向左,不完全居中。我的视图是横向模式,这与它有什么关系?我尝试按高度更改宽度,但没有用

ami*_*phy 4

默认情况下,ListPopupWindow与锚视图的左侧位置水平对齐。因此,我们应该通过计算当前中心与屏幕中心的差来对齐其左侧:

int screenWidth = getScreenSize().x;
if (isLandscape()) {
     screenWidth += getNavigationBarHeight();
}

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

insidelistPopupWindow.setHorizontalOffset(horizontalOffset);
Run Code Online (Sandbox Code Playgroud)

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

private int getRelativeLeft(View view) {
    if (view.getParent() == view.getRootView()) {
        return view.getLeft();
    } else {
        return view.getLeft() + getRelativeLeft((View) view.getParent());
    }
}
Run Code Online (Sandbox Code Playgroud)

并获取屏幕尺寸:

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);
}
Run Code Online (Sandbox Code Playgroud)

这样,锚视图水平在哪里以及它如何包裹在嵌套布局中并不重要,它ListPopupWindow总是位于屏幕的中间。