【问题标题】:Dragging popup window in Android在Android中拖动弹出窗口
【发布时间】:2014-03-02 09:42:49
【问题描述】:

我必须创建一个正方形的弹出窗口(高度为 400dp,宽度为 400dp)。现在,当我点击位于弹出窗口左上角的按钮时,我想拖动它。我在弹出窗口上的布局上设置了onTouch(),这是我用来拖动它的代码:

@Override
public boolean onTouch(View v, MotionEvent event) {
    int eventAction = event.getAction();

    switch (eventAction) {
        case MotionEvent.ACTION_MOVE: // Drag event

            xRow = (int) event.getRawX() - rootView.getWidth();
            yRow = (int) event.getRawY() - rootView.getHeight();             

            /* Updates the position of the popup on the screen */
            update(xRow, yRow, -1, -1);
            break;
    }

    return true;
}

问题是这似乎只适用于 Nexus 7。在 10 英寸的平板电脑上,它无法正常工作。当我将它拖到较大的平板电脑上时,我的手指和弹出窗口之间有一个空间。所以我假设我使用的测量单位不是正确的。我尝试使用 Metrics 但没有成功。

【问题讨论】:

  • 我看不出 rootView 的宽度与 getRawX() 值有什么关系。这里不应该有任何单位问题,因为一切都是原始像素,但我不确定你的计算逻辑是否有意义。
  • 通常,当我处理拖动对象时,我会在MotionEvent.ACTION_DOWN 中记录触摸的原始 X 和原始 Y 位置。同时,我注意到将要移动的视图的原始位置。然后在MotionEvent.ACTION_MOVE 中,我从新的 X 位置减去原来的 X 位置,得到 deltaX 值。我对 Y 做同样的事情以获得 deltaY。然后我将它们添加到正在移动的视图的原始位置,你会得到一个完美地跟踪你的手指的平滑移动。
  • 在向下动作中计算两个增量 dx 和 dy:dx = currentx - event_raw_x,对于 dy 和在移动动作中使用它们 new_x = event_raw_x + dx 和对于 new_y 相同
  • 我减去 rootView 是整个弹出窗口的宽度,因为我注意到弹出窗口的原点在左下角,这意味着当调用更新方法时,x 和 y 坐标将适用到那个,因为dragButton在左上角,它必须跟随我的手指,我必须减去弹出窗口的宽度。
  • 相信我这与宽度无关

标签: android drag popupwindow dimension


【解决方案1】:

劳拉,试试这个(放在 onCreate 中):

    final View cv = new View(this);
    setContentView(cv);

    TextView tv = new TextView(this);
    tv.setBackgroundColor(0xffeeeeee);
    tv.setTextColor(0xff000000);
    tv.setTextSize(24);
    tv.setText("click me\nthen drag me");
    tv.setPadding(8, 8, 8, 8);
    mPopup = new PopupWindow(tv, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    OnTouchListener otl = new OnTouchListener() {
        private float mDx;
        private float mDy;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();
            if (action == MotionEvent.ACTION_DOWN) {
                mDx = mCurrentX - event.getRawX();
                mDy = mCurrentY - event.getRawY();
            } else
            if (action == MotionEvent.ACTION_MOVE) {
                mCurrentX = (int) (event.getRawX() + mDx);
                mCurrentY = (int) (event.getRawY() + mDy);
                mPopup.update(mCurrentX, mCurrentY, -1, -1);
            }
            return true;
        }
    };
    tv.setOnTouchListener(otl);

    mCurrentX = 20;
    mCurrentY = 50;
    cv.post(new Runnable() {
        @Override
        public void run() {
            mPopup.showAtLocation(cv, Gravity.NO_GRAVITY, mCurrentX, mCurrentY);
        }
    });

【讨论】:

  • 非常、非常、非常感谢您:)它有效!我知道我的逻辑有问题,但我坚持这个想法,无论我尝试了多少其他事情,我的大脑都只考虑这个。再次感谢您启发我:)
  • 我很高兴有帮助:)
猜你喜欢
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多