Reputation: 2939
I got a popup window that is generated with the help of WindowManager
and with these params (as you can find in other stackoverflow questions):
new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
My question is similar to this one: Android: Drag View outside screen and also similar to this one: Dragging a view outside of RelativeLayout
The difference is that the WindowManager.LayoutParams
do not include any kind of margins, therefore it is not possible to use the margin tricks with relative layout etc.
Any idea on how I could drag the view outside of the android screen boundaries?
Thank you
Edit:
As you asked here is the related code that does the dragging for the time being
view.setOnTouchListener(new OnTouchListener {
def onTouch(view: View, motionEvent: MotionEvent): Boolean = {
val x = motionEvent.getRawX.toInt
val y = motionEvent.getRawY.toInt
motionEvent.getAction & MotionEvent.ACTION_MASK match {
case MotionEvent.ACTION_DOWN =>
val params = view.getLayoutParams.asInstanceOf[WindowManager.LayoutParams]
xDelta = x - params.x
yDelta = y - params.y
case MotionEvent.ACTION_UP =>
draggingOn = false
case MotionEvent.ACTION_MOVE =>
if (draggingOn) {
val params = view.getLayoutParams.asInstanceOf[WindowManager.LayoutParams]
params.x = x - xDelta
params.y = y - yDelta
//view.setLayoutParams(params)
windowManager.updateViewLayout(view, params)
//log log "current x is: " + x
//log log "current y is: " + y
} else {
//nop
}
case _ =>
//case MotionEvent.ACTION_POINTER_DOWN =>
//case MotionEvent.ACTION_POINTER_UP =>
}
false
}
})
above code is in scala but I guess you will not have any hard time reading it
Upvotes: 1
Views: 2076
Reputation: 51
Just use the flag FLAG_LAYOUT_NO_LIMITS in your LayoutParams:
new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT
)
Upvotes: 0
Reputation: 531
Edit : I found an easier solution : Just call :
setClippingEnabled(false);
and the following code works without the margins trick :
window.update(mOffsetX, mOffsetY, -1, -1, true);
Old response :
You cannot set an X position outside of the screen or set a margin on a PopupWindow layout params.
As a workaround, I use :
case MotionEvent.ACTION_DOWN:
mOrgX = (int) event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
mOffsetX = (int) event.getRawX() - mOrgX;
window.update(mOffsetX, mOffsetY, -1, -1, true);
As I said before you cannot change the PopupWindow margins but you can change the content view margins.
When the offsetX is larger than the starting X position of the popup, I start to change view margins
if (mStartingWindowPosition + mOffsetX <= 0
|| mWindowWith + mOffsetX > mScreenWidth) {
int delta = 0;
if (mOffsetX > 0) {
delta = window.getContentView().getWidth() + mOffsetX - mScreenWidth;
}
else {
delta = mStartingWindowPosition + mOffsetX;
}
params.rightMargin = -delta;
params.leftMargin = delta;
}
with :
if (mWindowWith == 0) {
mWindowWith = window.getContentView().getWidth();
mStartingWindowPosition = mScreenWidth / 2 - mWindowWith / 2; // my window is X centered
}
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) window.getContentView().getLayoutParams();
For me, it did the job
Tested on 4.X and 5.0 devices
Note : This code is not in production right now, so I don't know if there are side effects
Upvotes: 1
Reputation: 1504
Let your Dragged view is 20X20 and the entire screen is 100X100. Developing this effect that you wish can be done on following lines:
Detect the state when your dragged view cannot be contained in the screen boundaries Let current Drag position is (50,90), this will mean 10 units of your view should not be visible(vertically). On detecting this, you should set marginY = +10 units.
Similarly if Drag position is (-10,-15), this will mean 10 units of your view should not be visible(Horizonally) and 15 units(vertically). On detecting this, you should set marginY = -15 units and marginX= -10 units.
The thing to keep in mind is that the dimensions must be in same units. Hope this provides some assistance.
Upvotes: 0