【问题标题】:How to center a ListPopupWindow/Other views on Android horizontally?如何在 Android 上水平居中 ListPopupWindow/Other 视图?
【发布时间】:2020-07-17 17:32:45
【问题描述】:

我正在像这样创建一个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());
        }
    }

但我的弹出窗口稍微偏左,不完全居中。我的视图处于横向模式,与它有什么关系吗?我试过按高度改变宽度,但没有用

【问题讨论】:

    标签: java android android-layout


    【解决方案1】:

    默认情况下,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 始终位于屏幕中间。

    【讨论】:

    • 非常感谢,但是没用,看我更新。你觉得我做错了什么吗?
    • 这很奇怪!我会检查并回复。
    • 可以截图分享吗?
    • 没错!我想说的是,当您告诉设备是横向时。
    猜你喜欢
    • 2012-09-04
    • 2014-12-18
    • 1970-01-01
    • 2019-10-21
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    相关资源
    最近更新 更多