popupwindow_obj.showAsDropDown(clickbtn, -40, 18); // where u want show on view click event popupwindow.showAsDropDown(view, x, y);
Why is it that it is needed to specify absolute x and y co-ordinate values for pop up window object to be shown as drop down? Why does it eventhough not automatically show nearby of the control item that has been clicked enough, only for a one single time all though, once upon a time?
Thank you in advance.
From the android docs:
without cords
void showAsDropDown(View anchor) Display the content view in a popup
window anchored to the bottom-left corner of the anchor view.
with cords:
void showAsDropDown(View anchor, int xoff, int yoff) Display the
content view in a popup window anchored to the bottom-left corner of
the anchor view offset by the specified x and y coordinates.
From these 2 methods we can learn that there are 2 (actually 3) showAsDropDown methods.
The one without cords will do what you want automatically in the bottom-left corner. And the one with cords will just take some offset from the bottom-left corner. the offset will be determined by you (int xoff, int yoff), xoff stands for x offset and yoff stands for y offset.
Source
Related
I want to display the popup in the position where the user clicked on the screen, I use the function - showAtLocation (mainView, Gravity.TOP or Gravity.START, posX, posY), everything is fine in the x coordinate, but the Y coordinate of the popup is added higher than that place where the user clicked, and if the main view (mainView) is scrolled, then the popup generally flies to the very bottom and I just can't figure out what's wrong with the Y position.
posX and posY is the position where user touch the screen
UPDATED
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
posY = event.y.toInt()
return super.dispatchTouchEvent(event)
}
Thank you for updating the question!
I think showAtLocation() uses total coordinates, which start at the top,left of your screen. But (without seeing the complete context of your code) I think you are taking relative coordinates for the x and y coordinates.
If the viewgroup where you override the function dispatchTouchEvent() has for example a 24dp margin top, the (0;0) coordinate of this view is placed 24dp below the global (0;0) coordinate. Thus when you press at the top,left corner of your viewgroup, event.y.toInt() will return (0;0) and you will return 0 as posY. But your click was 24dp below the total 0 coordinate on your screen. So you will show the popup window 24dp too high.
The same will happen when you scroll down in your mainView. your screen is e.g. 1000px high and you scroll down two times the screenlength. event.y.toInt() could return now 2000px as a relative y coordinate. But the highest screen height is 1000px, so the popup window will be shown at the bottom of your screen, even when you clicked in the middle of your screen.
Does anyone know why when I use this code:
popupMenu.showAtLocation(containerView, Gravity.BOTTOM|Gravity.LEFT, x_offset, y_offset);
The y offset doesn't actually move the popup until it's greater than a certain number (in this case approx 120). For values under 120, nothing happens; for values over 120, the popup moves vertically up.
I'm guessing it's to do with the size of the popup, for which there doesn't seem to be a way to actually get the dimensions of to compensate for this threshold.
I'd like to know because a) there's scant information about this method, and b) I can't seem to get it to work to position my popup correctly.
Pretty old question but I would like to mention here that in case if anyone else is wondering what is the threshold for the yOffset - it is the top insets of the view you are passing to the showAtLocation() method.
In most cases this is your system bar height.
You can try to calculate the yOffset by
int desiredOffsetPx = 250;
int yOffset = desiredOffsetPx + systemWindowInsetTop
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, yOffset)
In order to get systemWindowInsetTop please check this answer
void showAtLocation (View parent,
int gravity,
int x,
int y)
Display the content view in a popup window at the specified location. If the popup window cannot fit on screen, it will be clipped. See WindowManager.LayoutParams for more information on how gravity and the x and y parameters are related. Specifying a gravity of NO_GRAVITY is similar to specifying Gravity.LEFT | Gravity.TOP.
You can find whole detail on this link : deveoper.android.com
I know I can use:
myPopup.showAtLocation(layout, Gravity.NO_GRAVITY, x, y);
// OR
myPopup.showAtLocation(layout, Gravity.TOP|Gravity.LEFT, x, y);
To open a PopupWindow that's drawn from [x, y] as the Top-Left of the PopupWindow, drawn towards to Bottom-Right.
What I want instead however, is to draw from [x, y] as the Top-Right of the PopupWindow, drawn towards the Bottom-Left.
Here is a picture to make it more clear (The dot is my [x, y] position and the rectangle is my PopupWindow. The first picture shows how it's normally done, and the second is what I want to achieve.):
So how do I correctly calculate the x and y of the second picture's gray point's location, while knowing the black point's location? I know the y can stay the same, but the x should be changed to something like:
x minus PopupWindow-width
The problem is that the PopupWindow's width and height are both set to wrap_content, so I don't know the size until after I draw it.
Does this mean I have to draw it (but make it invisible at first), then calculate the new x with the PopupWindow's MeasuredWidth in it's ViewTreeObserver's OnGlobalLayoutListener (to know when it's done rendering and the MeasuredWidth is known), then apply this new x and then make it Visible? Or is there an easier way to just let it draw at the correct position?
PS: I've also changed Gravity.NO_GRAVITY to Gravity.TOP|Gravity.RIGHT, if the PopupWindow is out of the screen it will automatically place it at the border of the Right/Top side (whichever side it's out of the screen).
You could get the size of your popup window by overriding the onMeasure method of the popup window (note that you have to subclass a View in order to do this). After that, you can calculate the offset of the x and y coordinates. Hope this helps.
I have a custom ImageView and in the OnDraw I have added some bitmap overlays. I can capture the click event for any overlay using action up type event in the OnTouchEvent callback. The thing is for me to display a popup window I must supply a view anchor for the popup window to show but I am using the bitmaps as anchors not a particular view, so I am stuck. I cannot find any sollution on the web regarding this issue. Passing the parent ImageView and adding the overlay x-y offsets (with Gravity.NO_GRAVITY) are not producing the desired result(Also the window arrow will not point correctly).
Use PopupWindow.showAtLocation
The problem is that x/y params into that function is offset relative to Window, to which anchor view belongs. You can see it clearly from function's source, where nothing from 'parent' is used except of its window token.
public void showAtLocation(View parent, int gravity, int x, int y) {
showAtLocation(parent.getWindowToken(), gravity, x, y);
}
So to make your offsets good, you have to determine anchor's position relative to its window.
For this, use
Rect rc = new Rect();
View.getWindowVisibleDisplayFrame(rc);
int[] xy = new int[2];
View.getLocationInWindow(xy);
rc.offset(xy[0], xy[1]);
now you have
inx x = rc.left, y = rc.top;
This is point of your ImageView's left-top corner relative to its window.
Finally show your PopupWindow at location relative to this point, and it should display correctly on top of your ImageView.
You referring to the below kind of view right...I would suggest you to follow the below link and implement the same in your case as well..If found difficult post ur comment and will get back to you..MAPViewBallons
From my knowledge x and y starts at the top left of the screen as 0,0
My question is there a calculation to get a positioning in the event? or another way(eg. another new class or method within this class)?
Now the question is vague so I want to add an example:
I remember in math close you have 4 sections in a graph top left, top right, bottom left, and bottom right.
Using the graph style to get variables in:
Getting position from top left to bottom left.
Getting position from bottom right to top right
Getting position from top left to bottom right
Use event.getX() and event.getY() then you can calculate coordinates in any section of graph used in math class.
x, height - y
x, height - y
width - x, height - y