【问题标题】:Drag & Drop for older Android not precise旧版 Android 的拖放不精确
【发布时间】:2012-07-12 18:31:05
【问题描述】:

所以我正在尝试制作一个“磁性诗歌”类型的应用程序。用户将在屏幕上移动各种 Button 小部件。我正在使用 Button 小部件,因为它最接近磁铁的外观,但我对其他选项持开放态度!

我的手指无法正确移动对象。它们很接近,但与我的手指并不完全一致。我手机上的 X 坐标似乎很好,但 Y 坐标已关闭。这可能是标题栏的原因吗?

private final static int DRAGGING_OFF = 0;
private final static int DRAGGING_ON = 1;

private int dragStatus;

private GestureDetector mGestureDetector; 
private int mOffsetX;
private int mOffsetY;
private LayoutParams mOldParams;
private RelativeLayout.LayoutParams lp;

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(!mGestureDetector.onTouchEvent(event)) {
        if(event.getAction() == MotionEvent.ACTION_MOVE) {
            if(dragStatus == DRAGGING_ON) {
                Log.e(VIEW_LOG_TAG, "Dragging! RAW -- " + event.getRawX() + " : " + event.getRawY() + " NOT RAW -- " + event.getX() + " : " + event.getY());
                int rawX, rawY;
                int finalX, finalY;

                rawX = (int) event.getRawX();
                rawY = (int) event.getRawY();

                finalX = rawX - mOffsetX;
                finalY = rawY - mOffsetY;

                lp.setMargins(finalX, finalY, 0, 0);
                this.setLayoutParams(lp);
            }

            return true;
        } else if(event.getAction() == MotionEvent.ACTION_UP) {
            if(dragStatus == DRAGGING_ON) {
                dragStatus = DRAGGING_OFF;
                Log.e(VIEW_LOG_TAG, "Stopped dragging!");
            }

            return true;
        } else {
            return super.onTouchEvent(event);
        }
    } else {
        return true;
    }
}

private final GestureDetector.SimpleOnGestureListener mListener = new GestureDetector.SimpleOnGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {          
        int[] location = new int[2];
        Log.e(VIEW_LOG_TAG, "Down! RAW -- " + e.getRawX() + " : " + e.getRawY() + " NOT RAW -- " + e.getX() + " : " + e.getY());
        dragStatus = DRAGGING_ON;

        // Sets the current location of the View in the int[] passed to it; x then y.
        getLocationInWindow(location);
        Log.e(VIEW_LOG_TAG, "Down location: " + location[0] + " " + location[1]);

        mOffsetX = (int) e.getRawX() - location[0];
        mOffsetY = (int) e.getRawY() - location[1];
        mOldParams = getLayoutParams();

        return true;
    }
};

【问题讨论】:

    标签: android button view drag-and-drop gesturedetector


    【解决方案1】:

    我认为问题在于您没有获得当前接触点 Y 和缓存的最后一个接触点 y 的 DELTA。你需要这样的东西:

    @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            final TextView textView = (TextView) findViewById(R.id.text);
            final ImageView image = (ImageView) findViewById(R.id.image);
            matrix.setTranslate(1f, 1f);
            image.setImageMatrix(matrix);
            image.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    matrix.getValues(m); //copy matrix values into array
    
                    PointF currentXYTouchPoint = new PointF(event.getX(), event.getY());
    
                    switch(event.getAction()) {
                        case MotionEvent.ACTION_DOWN: //start of pressed gesture
                            lastXYTouchPoint.set(event.getX(), event.getY()); //save the last touchpoint
                            mode = DRAG;
                            break;
                        case MotionEvent.ACTION_MOVE:
                            //calculate the change in finger position
                            float deltaX = currentXYTouchPoint.x - lastXYTouchPoint.x;
                            float deltaY = currentXYTouchPoint.y - lastXYTouchPoint.y;
                            matrix.postTranslate(deltaX, deltaY); //move the entire image by the deltas
                            image.setImageMatrix(matrix);
    
                            // save this last starting touchpoint
                            lastXYTouchPoint.set(currentXYTouchPoint.x, currentXYTouchPoint.y);
                            break;
                    }
    
                    textView.setText("TouchPoint started at " + currentXYTouchPoint.x + ", " + currentXYTouchPoint.y + " & the matrix is now " + Arrays.toString(m));
                    return true;
                }
            });
    
        }
    

    根据你自己的目的调整它,但基本的想法就在那里。

    【讨论】:

    • 这似乎是一种可行的方法。我只需要针对 getLocationInWindow() 对其进行测试,以确保我从那里得到的数字可以直接用于计算并传回 LayoutParams.setMargins()
    • 所以事实证明我遇到的问题与使用我的方法或使用您建议的 delta 方法无关。它似乎与标题栏和状态栏高度有关。我得到的数字是相对于屏幕的,但是关于我设置的位置的信息应该是相对于窗口的,所以它在 Y 坐标上是关闭的。有人帮我找到了这个:andmobidev.blogspot.com/2010/01/…
    猜你喜欢
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    相关资源
    最近更新 更多