Search code examples
javaandroidandroid-activitytouchdraggable

OnTouch MotionEvent Action Move not triggering


I'm trying to get X, Y coordinates while I'm dragging my button, but for some reason, the code bellow attached on touch listener triggers only twice instead of constant update while dragging, even with trothing I will be satisfied in order to improve performance, but as I said, onTouch method triggered just on action down, and one more time later.

This is my code:

final Button dragBtn = (Button) findViewById(R.id.MyTestButton);

    dragBtn.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent me) {
        // TODO Auto-generated method stub
        ClipData data = ClipData.newPlainText("", "");
        View.DragShadowBuilder shadow = new View.DragShadowBuilder(dragBtn);
        v.startDrag(data, shadow, null, 0);
        int action = me.getAction();


        if (action==MotionEvent.ACTION_DOWN) {

            Log.i("TEST", "ACTION_DOWN");
            return true;
        }


        if (action==MotionEvent.ACTION_MOVE){
            Log.i("TEST", "ACTION_MOVE");

            float x = me.getX();
            float y = me.getY();

            //TODO: Rest of my code here.

            return true;
        }

        if (action==MotionEvent.ACTION_UP){

            Log.i("TEST", "ACTION_UP");
            return true;
        }

        Log.i("TEST", "UKNOWN ACTION");
        return true;
    }
});

And in log I have just:

ACTION_DOWN
WindowManager﹕ Drag already in progress
UKNOWN ACTION

Solution

  • You want to capture the X and Y coordinate data in your OnDragListener not your OnTouchListener. For the whole time that you are dragging the object around the screen, Android interprets that as one single ACTION_MOVE event, hence you only get data once from that. Place the following code inside your custom OnDragListener class:

    @Override
    public boolean onDrag(View v, DragEvent event) {
        int action = event.getAction();
        float xCoord;
        float yCoord;
        if(action == DragEvent.ACTION_DRAG_LOCATION) {
            xCoord = event.getX();
            yCoord = event.getY();
        }
        return event.getResult();       //returns true for valid drop or false for invalid drop
    }
    

    Somewhere else in your custom OnDragListener class, you will have to do something with that xCoord and yCoord data. For example in my app, I have a TextView on my "debug" version of the app where I display the xCoord and yCoord data. I execute the TextView.setText() method right after I get those two values in my if(action == DragEvent.ACTION_DRAG_LOCATION){... section.

    Hope this helps.