-->

Simulate smooth Drag Event programmatically

2020-07-17 07:40发布

问题:

I used custom DragLinearLayout. All child I added using addDragView() are draggable (user interaction).
I want to simulate Drag Event for clicked View (smooth move to the bottom of Layout).

ACTION_DOWN -> ACTION_MOVE -> ACTION_UP

I tried this code, but it didn't work.

long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis();
float x = view.getLeft();
float y = view.getTop();
int metaState = 0;
MotionEvent downEvent = MotionEvent.obtain(
                            downTime,
                            eventTime + 1000,
                            MotionEvent.ACTION_DOWN,
                            x,
                            y,
                            metaState
                    );
view.dispatchTouchEvent(downEvent);

MotionEvent moveEvent = MotionEvent.obtain(
                            downTime,
                            eventTime + 1000,
                            MotionEvent.ACTION_MOVE,
                            x,
                            y + 300,
                            metaState
                    );
view.dispatchTouchEvent(moveEvent);

MotionEvent upEvent = MotionEvent.obtain(
                            downTime,
                            eventTime + 1001,
                            MotionEvent.ACTION_UP,
                            x,
                            y + 300,
                            metaState
                    );
view.dispatchTouchEvent(upEvent);

回答1:

I had the same problem, I had to simulate the listview to overscroll.

After some tweak, I successfully did the work.

Here is what I did: (overScrollDown() is a function in My Custom ListView)

You can see detail here in this gist. Also the screencast

public void overScrollDown() {
    post(new Runnable() {
        @Override
        public void run() {
            final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_DOWN, getWidth() / 2, getHeight() / 2, 0);
            dispatchTouchEvent(event);
            event.recycle();
        }
    });

    postDelayed(new Runnable() {
        @Override
        public void run() {
            final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_MOVE, getWidth() / 2, getHeight() / 2, 0);
            dispatchTouchEvent(event);
            event.recycle();
        }
    }, 50);

    postDelayed(new Runnable() {
        @Override
        public void run() {
            final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_MOVE, getWidth() / 2, getHeight() / 2 + 400, 0);
            dispatchTouchEvent(event);
            event.recycle();
        }
    }, 100);

    postDelayed(new Runnable() {
        @Override
        public void run() {
            final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_UP, getWidth() / 2, getHeight() / 2 + 400, 0);
            dispatchTouchEvent(event);
            event.recycle();
        }
    }, 3000);
}

Btw. the scroll down operation can be smooth with more ACTION_MOVE Event..