Multi Touch Madness
This is part 1 in a series where I convert a natively coded Android application into a cross-platform application using Sencha Touch. To get a bit more background, take a look at the introductory post I wrote.
It wasn’t long before I had my first “Uh oh…” moment, whilst attempting to implement the touch controls. I very heavily relied on the ability to detect multiple different touch points on the screen in the Android application but, to the best of my knowledge, this is not possible with Sencha Touch. Sencha Touch does offer multi touch capability to an extent, but this is through predefined gestures which are limited to the following:
- touchstart
- touchmove
- touchend
- dragstart
- drag
- dragend
- tap
- singletap
- doubletap
- longpress
- swipe
- pinch
- rotate
So the only multi touch gestures we are able to use are pinch and rotate. You can have a play with the touch events in Sencha’s Kitchen Sink application here. My first thoughts were “Crap… well now what?” with a little restructuring though I was able to come up with an effective solution. In the native application, the user would hold their finger down on the screen to start the timer and it would stop as soon as they removed it. This is the only feature I could not keep (which is probably a good thing, this was not universally liked) and I moved to a more traditional start / stop method. I’ll summarise the changes I made below:
- Hold to start timer -> Doubletap to start timer
- Release to stop timer -> Doubletap to stop timer
- Tap with a finger whilst the timer is running to record a lap (unchanged)
- Slide to the edges of the screen to change songs -> Swipe to change songs
With everything seemingly all sorted, I pushed ahead with the coding and didn’t really run into too many problems. Although one thing that did trip me up for a little bit was the fact that panels do not fire tap events by default, in order to get this working you have to manually trigger the event from the element in the panel, the following code got this working for me:
listeners: {
initialize: function(event) {
this.element.addListener("doubletap", function(event){
console.log('toggleStartStop');
});
}
The difference between tap and singletap
This is really the only outstanding issue at the moment and I’m not sure whether this is going to be a problem in the long run. I haven’t played with touch events a lot in the past, so when I started coding this I wondered exactly what the difference was between tap and singletap. A tap registers immediately, whereas a singletap waits to see if it is going to be a doubletap before it fires. For example if I tap the screen once the following events will trigger:
touchstart
touchend
tap
singletap
But if I double tap the screen the following events will fire:
touchstart
touchend
tap
touchstart
touchend
tap
doubletap
So in this example you can see that the tap event fires twice, but the singletap event never fires at all. The problem with my setup however comes when the user wants to record a lap. To do this they tap the screen so obviously I have to either use tap or singletap. If I use tap though, if the user is doubletapping to stop the timer the application will think that they are trying to record 2 laps. However, if I use singletap there is a small delay (a few milliseconds) before it is fired to see if the second tap is coming which will lead to the lap time being off by a few milliseconds. I’ll likely revisit this issue later down the track.
I’m happy with the progress so far and all the touch controls are coded and working so I’m ready to move onto the next step which will be implementing the timer!
UPDATE: Part two is now available here.