I'm creating a ListPopupWindow
like this:
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();
I tried to do simple math
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;
}
to center it horizontally. It worked on my phone but not on others, so I suspect something is wrong about my asumptions. But I also suspect there's a better way of solving this.
How do I simply center something horizontally programatically?
PS: the same ListPopupWindow but with different number of elements is getting placed on different positions on screen. Why this happens?
UPDATE:
Based on the answer below,
I tried
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);
and did
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());
}
}
but my popup is slightly to the left, not exactly centered. My view is in landscape mode, does it have anything to do with it? I tried changing width by height but it didn't work
By default, the ListPopupWindow
gets horizontally aligned with the left position of the anchor view. So, we should align its left side by calculating the difference of the current center from the screen center:
int screenWidth = getScreenSize().x;
if (isLandscape()) {
screenWidth += getNavigationBarHeight();
}
int horizontalOffset = (screenWidth / 2) - (getRelativeLeft(view) + insidelistPopupWindow.getWidth() / 2);
insidelistPopupWindow.setHorizontalOffset(horizontalOffset);
getRelativeLeft()
helps us to find the real left position of the anchor view regarding the screen (not its parent ViewGroup
).
private int getRelativeLeft(View view) {
if (view.getParent() == view.getRootView()) {
return view.getLeft();
} else {
return view.getLeft() + getRelativeLeft((View) view.getParent());
}
}
And to get the screen size:
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);
}
In this way, it doesn't matter where is the anchor view horizontally and how it's wrapped in nested layouts, the ListPopupWindow
always resides in the middle of the screen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With