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:
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
Updated Sdk Version, Getting Classnotfoundexception: Android.Support.V4.View.Viewpager
Check Whether Lock Was Enabled or Not
How to Rotate Textview 90 Degrees and Display
Mediametadataretriever.Getframeattime() Returns Only First Frame
Error: Mapfragment Cannot Be Cast to Android.Support.V4.App.Fragment
5.1 Crash - a Taskdescription's Primary Color Should Be Opaque
Kitkat Kills: Not Allowed to Load Local Resource: File:///Android_Asset/Webkit/Android-Weberror.Png
How to Check If Music Is Playing by Using a Broadcast Receiver
How to Add a Hint in Spinner in Xml
Do Gcm Registration Id's Expire
Difference Between Android: and App: Prefix in Android Xml
Triggering Event When Button Is Pressed Down in Android
How to Use Mediacodec Without Mediaextractor for H264
Refresh or Force Redraw the Fragment