java - 如何在 Android 上水平居中 ListPopupWindow/Other 视图?
问题描述
我正在创建一个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());
}
}
但我的弹出窗口稍微偏左,不完全居中。我的视图处于横向模式,与它有什么关系吗?我尝试按高度更改宽度,但没有用
解决方案
默认情况下,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
始终位于屏幕中间。
推荐阅读
- html - 如何为内部块制作滚动?
- sql - 使用 ON CONFLICT 时是否可以仅检查 postgres 中主键的一部分
- angular - 基于位置的 AR:使用 Angular 创建原生应用
- rasa - 回答如何从 Rasa<->Google 聊天集成后发送到 Rasa 服务器的环聊消息中获取用户电子邮件 ID
- sql - 如何计算每一行的值差
- javascript - 不会为所有输入字段存储数据
- javascript - 从 aspx 将 json 传递给 javascript 方法
- maven - 打开 zip 文件时出现 Maven 构建失败错误
- php - 数据库表关系,指定所需条件
- python - 根据列表字典python的输入获取名称