如何在Android屏幕外拖动弹出视图?

时间:2014-06-20 09:38:59

标签: android drag android-windowmanager

我有一个弹出窗口,它是在WindowManager和这些参数的帮助下生成的(正如你在其他stackoverflow问题中找到的那样):

new WindowManager.LayoutParams(
  ViewGroup.LayoutParams.WRAP_CONTENT,
  ViewGroup.LayoutParams.WRAP_CONTENT,
  WindowManager.LayoutParams.TYPE_PHONE,
  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
  PixelFormat.TRANSLUCENT
)

我的问题与此类似:Android: Drag View outside screen也类似于此问题:Dragging a view outside of RelativeLayout

不同之处在于WindowManager.LayoutParams不包含任何类型的边距,因此不可能使用相对布局等的边距技巧。

有关如何将视图拖动到Android屏幕边界之外的任何想法吗?

谢谢

修改的:
正如你在这里问的那样是暂时拖动的相关代码

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
  }
})

上面的代码是scala,但我想你不会有任何阅读它的困难

3 个答案:

答案 0 :(得分:0)

让您的拖动视图为20X20,整个屏幕为100X100。您可以通过以下方式开发您想要的效果:

  1. 检测拖动视图无法包含在屏幕边界中的状态 让当前拖动位置为(50,90),这意味着您的视图的10个单位不应该是可见的(垂直)。在检测到这个时,你应该设置marginY = +10个单位。

  2. 同样,如果拖动位置为(-10,-15),则表示视图的10个单位不可见(水平)和15个单位(垂直)。在检测到这个时,你应该设置marginY = -15单位和marginX = -10单位。

  3. 要记住的是尺寸必须是相同的单位。 希望这能提供一些帮助。

答案 1 :(得分:0)

编辑:我找到了一个更简单的解决方案: 请致电:

setClippingEnabled(false);

以下代码没有边距技巧:

window.update(mOffsetX, mOffsetY, -1, -1, true);

旧回应:

您不能在屏幕外设置X位置或在PopupWindow布局参数上设置边距。

作为解决方法,我使用:

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);

如前所述,您无法更改PopupWindow边距,但可以更改内容视图边距。

当offsetX大于弹出窗口的起始X位置时,我开始更改视图边距

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();

对我而言,它完成了这项工作

在4.X和5.0设备上测试

注意:此代码目前尚未生产,因此我不知道是否存在副作用

答案 2 :(得分:0)

只需在您的LayoutParams中使用标记FLAG_LAYOUT_NO_LIMITS

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
)
相关问题