0

I have two activities: ActivityA & ActivityB. ActivityA is listening for motion events. When a scroll event takes place, ActivityB is launched immediately.

ActivityB has a scrollable content inside, and I want it to begin scrolling this content immediately, without forcing users to lift their finger up. The transition has to be transparent, the scroll gesture shouldn't stop between activities, but continue smoothly.

In other words, the problem is that ActivityB is not reacting to motion events unless users lift their finger up and touch the screen again.

How can I solve this?

EyesClear
  • 28,077
  • 7
  • 32
  • 43
  • Can't you pass the last MotionEvent information from A to B, and then simulate a `ACTION_DOWN` once B is started? – NSimon Apr 22 '16 at 08:26
  • @NicolasSimon I think it's the right direction and I've been exploring it, so far unsuccessfully. – EyesClear Apr 22 '16 at 08:40

1 Answers1

1

All right, I'll try to put here more information than in my first comment. So first of all, the system is not supposed to allow this behavior, as discussed in that thread : https://groups.google.com/forum/#!topic/android-platform/d6Kt1DhCAtw

That being said, I came across this issues when willing to automate UI tests on my applications, especially for image manipulation, where I wanted to simulate fingers on the screen.

Here's a snippet that you could potentially apply to your Activity B :

Step 1 : Pass X and Y coordinates of the last MotionEvent from Activity A to Activity B

Step 2 : Retrieve these values in Activity B, and then apply :

private void continueScrolling(int posX, int posY) {
  long downTime = SystemClock.uptimeMillis();
    long eventTime = SystemClock.uptimeMillis();

    MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[1];
    MotionEvent.PointerCoords pc1 = new MotionEvent.PointerCoords();
    pc1.x = posX;
    pc1.y = posY;
    pc1.pressure = 1;
    pc1.size = 1;
    pointerCoords[0] = pc1;

    MotionEvent.PointerProperties[] pointerProperties = new MotionEvent.PointerProperties[1];
    MotionEvent.PointerProperties pp1 = new MotionEvent.PointerProperties();
    pp1.id = 0;
    pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
    pointerProperties[0] = pp1;

    MotionEvent event;
    // send the initial touches (this seems to be to "wake up" the view, you might not need it in a non-testing context though)
    event = MotionEvent.obtain(downTime, eventTime,
            MotionEvent.ACTION_DOWN, 1, pointerProperties, pointerCoords,
            0, 0, // metaState, buttonState
            1, // x precision
            1, // y precision
            0, 0, // deviceId, edgeFlags
            InputDevice.SOURCE_TOUCHSCREEN, 0); // source, flags
    theViewYouWantTomove.dispatchGenericMotionEvent(event);

    event = MotionEvent.obtain(downTime, eventTime,
            MotionEvent.ACTION_DOWN,
            1, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0,
            InputDevice.SOURCE_TOUCHSCREEN, 0);
    theViewYouWantTomove.dispatchGenericMotionEvent(event);
}
NSimon
  • 5,212
  • 2
  • 22
  • 36
  • Thanks. I don't see how the link you posted is related to this issue. Anyway, I tried to follow your idea, but without luck. – EyesClear Apr 28 '16 at 11:34
  • Well, the OP of the link is trying to achieve the same as you are : simulate clicks on views. – NSimon Apr 28 '16 at 12:12