The fix for this in Sencha 2.1 was more complicated than the first code i posted. It seems to happen on all Android 4 phones i've tried, whenever using multi touch. What actually happens is, when releasing a multi touch, one of the released points is never reported to the Sencha event processor. I expect this is an error in Android, like many others. The weird behavior is because Sencha thinks you're still holding one of your fingers on the screen.
I solved it by first disabling all event processors i didn't need.
Code:
Ext.application({
name: 'app',
// disable all the below recognizers
eventPublishers: {
touchGesture: {
recognizers: {
rotate: null,
doubleTap: null,
longPress: null,
swipe: null
}
}
},
...
})
Then overriding the touch event processor so it's able to reset itself
Code:
Ext.define('app.overrides.TouchGesture', {
override: 'Ext.event.publisher.TouchGesture',
reset: function(e){
if(Ext.os.is.Android4 && this.currentTouchesCount > 0){
e.changedTouches = Ext.Object.getValues(this.currentTouches);
this.onTouchEnd(e);
}
}
});
Then detect when the error occurs by overriding the Pinch detector
Code:
window.orgPinchEndMethod = Ext.event.recognizer.Pinch.prototype.end;
Ext.define('app.overrides.Pinch', {
override: 'Ext.event.recognizer.Pinch',
end: function(e){
var wasTracking = this.isTracking,
result = window.orgPinchEndMethod.apply(this, arguments);
if(wasTracking){
this._resetDetection(e);
}
return result;
},
_resetDetection: function(e){
// At this point, the pinch event is tracking meaning there should be two fingers on the screen.
// There is only one active touch event tho, meaning that Android has not propagated the touch end event,
// which would end the tracking. This now has to be done manually through this nasty hack
var tg = Ext.event.Dispatcher.getInstance().getPublishers().touchGesture;
setTimeout(function(){
tg.reset(e);
}, 0);
}
});
Mind that this solution uses one touch to fix itself when the error occurs.