1
\$\begingroup\$

I've implemented a touchup listener for an actor in stage. Now what happens is that when user touch downs the sprite and releases finger, its all good. The problem is when user touch downs the finger, and drag it somewhere else (possibly to cancel the touch) and releases, it still fires the touch up event as if nothing ever happened. How do I stop that? Here's my code:

voiceToggle.addListener(new InputListener() {
    @Override
    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
        System.out.println("touched");
        return true;
    }

    @Override
    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
        System.out.println(event); // still fires even if not on original touchdown element
    }
});
\$\endgroup\$
  • \$\begingroup\$ I've never worked wit LibGDX, and this is probably just a workaround but: perhaps you could make sure that the x and y are above the button on touchUp events before firing the action? \$\endgroup\$ – Vaillancourt Dec 16 '16 at 10:58
  • \$\begingroup\$ @AlexandreVaillancourt but that apparently defeats the purpose of setting click listener on a specific actor. If I've to check that everytime, why wouldn't I use a general listener for screen. \$\endgroup\$ – mehulmpt Dec 16 '16 at 16:03
  • 1
    \$\begingroup\$ You're right; I was only suggesting a temporary fix while you were looking for the real solution :) \$\endgroup\$ – Vaillancourt Dec 16 '16 at 16:09
  • \$\begingroup\$ @AlexandreVaillancourt Yeah. I understand. But I've so many actors/buttons that it'll be an ugly fix to put an if condition in every one of those :) \$\endgroup\$ – mehulmpt Dec 16 '16 at 16:30
0
\$\begingroup\$

Oddly enough, the documentation for InputListener appears to be a little different than the source. If you look at the source for InputListener, it's actually behaving as it's supposed to:

/** Called when a mouse button or a finger touch goes down on the actor. If true is returned, this listener will receive all
 * touchDragged and touchUp events, even those not over this actor, until touchUp is received. Also when true is returned, the
 * event is {@link Event#handle() handled}.
 * @see InputEvent */
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
    return false;
}

/** Called when a mouse button or a finger touch goes up anywhere, but only if touchDown previously returned true for the mouse
 * button or touch. The touchUp event is always {@link Event#handle() handled}.
 * @see InputEvent */
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
}

A simple way to solve this would be to put a check in your touchUp() method that checks to see if x and y are still on top of the actor. If they're not, don't do anything.

I suspect the reason they built it this way was to give you the option of choosing whether you want to do anything or not (while there is a separate onDragged method, you might want to do something special with the new position).

\$\endgroup\$
0
\$\begingroup\$

I actually found that ClickListener class contains another method clicked which fires just like I want it to (if the figure is on actor).

voiceToggle.addListener(new ClickListener() {
    @Override
    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
        System.out.println("touched");
        return true;
    }

           @Override
            public void clicked(InputEvent event, float x, float y) {
                // all the stuff
                super.clicked(event, x, y);
            }  

    @Override
    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
        System.out.println(event); // still fires even if not on original touchdown element
    }
});
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.