Can't Handle Both Click and Touch Events Simultaneously

Can't handle both click and touch events simultaneously

There is a subtle, yet very important difference between the ClickListener and the TouchListener. The TouchListener is executed before the view can respond to the event. The ClickListener will receive its event only after the view has handled it.

So when you touch your screen, the TouchListener is executed first and when you return true for your event, the ClickListener will never get it. But if you press the trackball of your device, the ClickListener should be fired because the TouchListener will not respond to it.

handle both mouse and touch events on touch screens

You should rather check availability of touch interface and bind events according to that.

You can do something like this:

(function () {
if ('ontouchstart' in window) {
window.Evt = {
PUSH : 'touchstart',
MOVE : 'touchmove',
RELEASE : 'touchend'
};
} else {
window.Evt = {
PUSH : 'mousedown',
MOVE : 'mousemove',
RELEASE : 'mouseup'
};
}
}());

// and then...

document.getElementById('mydiv').addEventListener(Evt.PUSH, myStartDragHandler, false);


If you want to handle both in same time and browser does not translate well touch events into mouse events, you can catch touch events and stop them - then corresponding mouse event shouldn't be fired by browser (you won't have double events) and you can fire it yourself as mouse event or just handle it.

var mydiv = document.getElementsById('mydiv');
mydiv.addEventListener('mousemove', myMoveHandler, false);
mydiv.addEventListener('touchmove', function (e) {
// stop touch event
e.stopPropagation();
e.preventDefault();

// translate to mouse event
var clkEvt = document.createEvent('MouseEvent');
clkEvt.initMouseEvent('mousemove', true, true, window, e.detail,
e.touches[0].screenX, e.touches[0].screenY,
e.touches[0].clientX, e.touches[0].clientY,
false, false, false, false,
0, null);
mydiv.dispatchEvent(clkEvt);

// or just handle touch event
myMoveHandler(e);
}, false);

Handling button click and button touch simultaneously in Kotlin

Because onTouch and onClick will conflict,When you consume the event in onTouchListener, that is return@setOnTouchListener true; will not execute the click again, if you want the click event to be executed after ACTION_UP, just return@setOnTouchListener false

Like Selvin said, if you just want to change the color or background of the button when pressed, you shouldn't do it this way,use drawable selector is the best!

Simultaneous touch events handling on multiple views in Android

If I'm not wrong, you want to process the same touch event both on the top and bottom view. According to Android touch architecture, you can't handle touch events from multiple views at the same time. Either you have to process it inside the onTouchEvent() method or pass to the next view. You also need to wait till the top view finish processing the MotionEvent() and let the child view to handle.

Here's a possible solution using RxAndroid approach,

Inside your canvas view's MotionEvent(),

@Override
public boolean onTouchEvent(MotionEvent event) {

// process all touch events (UP/DOWN/MOVE)

//send events as observable
RxBus.getInstance().sendMotionEvent(event);

return true;
}

This will observe the motion events and notify all observers.

Now, inside your viewpager's onResume() subscribe for the motion events so that whenever a change is made from the canvas It'll immediately pass the events.

Subscription RxBus _rxBus = RxBus.getInstance();
subscription = _rxBus.getMotionEvent()
.subscribe(new Action1<MotionEvent>() {
@Override
public void call(MotionEvent event) {
// call the onTouchEvent of your widget e.g. ImageView and pass the received event
// this will apply the same touch event that was applied in the canvas

// .onTouchEvent(event) is important to override the onTouchEvent() of your widget that will use the touch event
imageView.onTouchEvent(event);
}
});

The RxBus class is given below,

public class RxBus {

private static RxBus instance;

private final PublishSubject<MotionEvent> motion_event = PublishSubject.create();

public static RxBus getInstance() {
if (instance == null) {
instance = new RxBus();
}
return instance;
}

public void sendMotionEvent(MotionEvent motionEvent) {
motion_event.onNext(motionEvent);
}

public Observable<MotionEvent> getMotionEvent() {
return motion_event;
}
}

How to bind 'touchstart' and 'click' events but not respond to both?

Update: Check out the jQuery Pointer Events Polyfill project which allows you to bind to "pointer" events instead of choosing between mouse & touch.


Bind to both, but make a flag so the function only fires once per 100ms or so.

var flag = false;
$thing.bind('touchstart click', function(){
if (!flag) {
flag = true;
setTimeout(function(){ flag = false; }, 100);
// do something
}

return false
});

How to handle hybrid devices in click/touch events properly?

You could use a Subject and debounce for a couple of milliseconds so you only have one event, something like this:

import {Component, Renderer} from '@angular/core'
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/debounceTime';

@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
</div>
`,
})
export class App {
name = 'Angular2';
subject = new Subject();

constructor(renderer: Renderer) {
renderer.listenGlobal('document', 'touchend', (e) => {
console.log('touchend');
this.subject.next(e);
});
renderer.listenGlobal('document', 'click', (e) => {
console.log('click');
this.subject.next(e);
});

this.subject.debounceTime(100).subscribe(event => {
console.log(event); //do stuff here
})
}
}

So when you use hybrid devices, you will get this:
Sample Image

Two events were fired, but you only get one on your Observable.

You can play around in this plunker

React onClick and onTouchStart fired simultaneously

Solved this problem using similar events between touch and mouse. touchStart/mouseDown or touchEnd/mouseUp. It fires one or another, according to each situation.

<div
className={myClasses}
onMouseUp={this.myHandle}
onTouchEnd={this.myHandle}

</div>


Related Topics



Leave a reply



Submit