Objective
In this section, you will learn how to support more than simple taps in your Titanium apps. You'll examine various gestures, including shakes and swipes, and also learn how to manage global events within the Android app lifecycle.
Contents
Mobile devices offer opportunity for inputs that go beyond simple taps. "Best of breed" apps should use those inputs whenever appropriate. These include:
- Shakes
- Swipes
- Touches
- Pinching
- Long presses
- and accelerometer inputs by which you gauge pitch, roll, and yaw.
We'll breeze through each of these in this section.
Shake
You can determine when a user shakes their device via the Ti.Gesture
module.
Ti.Gesture.addEventListener( 'shake' , function (e) { alert( 'shaken at ' +e.timestamp); }); |
You could use the timestamp
property to determine if a user has shaken the device for a given amount
of time.
The iOS simulator supports simulated shake events. Choose Hardware > Shake Device to "shake" the simulator. The Android emulator does not support simulated shake events.
Swipe
Swipes are left/right tap & drag the finger gestures (where scrolls are up/down drags). Support for swipes are built into most of the Titanium UI components.
var view = Ti.UI.createView(); view.addEventListener( 'swipe' , function (e){ alert( 'You swiped to the ' +e.direction); }); |
Touch
Touch events are associated with the Titanium UI components. There are four touch events:
touchstart
– fired when a user's finger first contacts the device's screen.touchend
– fired when the user lifts his or her finger.touchmove
– fires continuously as the user drags his or her finger on the screen.touchcancel
– fired if the operating system interrupts an ongoing touch event, such as when a phone call is received.
The event object associated with these events has only two useful properties: the X and Y coordinates of the event. You can use that information to track the user's finger across your app's UI.
On the Android platform, other gesture events, such as longpress
and swipe
, cancel touch events, so a touchend
event may not fire after a touchstart
event.
Pinch
Added in the 1.8 release of the APIs, the pinch event is currently supported
on iOS only. (Android support is in the works.) This event is associated
with UI components and its event object has the useful scale
property as shown here:
var view = Ti.UI.createView(); view.addEventListener( 'pinch' , function (e){ alert( 'You pinched to ' + e.scale*100 + '%' ); }); |
Long press
Also added in version 1.8 is support for long press events. These are like taps or clicks that last for more than an arbitrary amount of time. Keep in mind the native conventions for use of the long press. For example, on Android, a long press typically displays a pop-up of options or actions (sort of like a context menu on a desktop operating system).
Support for long presses are now built into most of the Titanium UI components.
var view = Ti.UI.createView(); view.addEventListener( 'longpress' , function (e){ alert( 'You pressed at coordinates ' + e.x + ' / ' + e.y); }); |
Accelerometer
Some iOS and Android devices include an accelerometer, which you can use to track pitch, roll, and yaw. Perhaps you've seen racing games where you steer by tipping your device from side to side. You can use the accelerometer for similar user input in your Titanium apps.
// labelTime, labelX, labelY, and labelZ are Ti.UI.Labels Ti.Accelerometer.addEventListener( 'update' , function (e){ labelTime.text = e.timestamp; labelX.text = 'x: ' + e.x; labelY.text = 'y:' + e.y; labelZ.text = 'z:' + e.z; }); |
If you run this code or the accelerometer.js sample in the Kitchen Sink,
you'll see that the update
event is fired rapidly and the three axis values are extremely sensitive
(many decimal places). To use the accelerometer successfully in your app,
you'll want to average values over time and round the values to an appropriate
level of precision for your needs. A Google search for smoothing accelerometer data will give you many code examples to draw from.
(Keep in mind that the simulator/emulator doesn't support the accelerometer. So, you'll have to test on a device.)
Managing events within the app's lifecycle
Because Android is a multitasking environment, it's important that you
remove global event listeners when your app is put into the background.
(Global events include Ti.App, Ti.Gesture, Ti.Accelerometer, Ti.Geolocation,
etc.) If you don't, the hardware that supports those global events will
remain powered on and events will continue to be fired. Removing event
listeners thus helps limit the associated battery-drain by powering down
the device components. To remove an event listener, you must pass the same
function signature to removeEventListener()
as you passed to addEventListener()
. For that reason, you should generally follow this format:
// labelTime, labelX, labelY, and labelZ are Ti.UI.Labels var accelerometerAdded = false ; var accelerometerCallback = function (e){ labelTime.text = e.timestamp; labelX.text = 'x: ' + e.x; labelY.text = 'y:' + e.y; labelZ.text = 'z:' + e.z; }; Ti.Accelerometer.addEventListener( 'update' , accelerometerCallback); accelerometerAdded = true ; if (Titanium.Platform.name == 'android' ) { Ti.Android.currentActivity.addEventListener( 'pause' , function (e) { // called when app is put into the background if (accelerometerAdded) { Ti.API.info( "removing accelerometer callback on pause" ); Ti.Accelerometer.removeEventListener( 'update' , accelerometerCallback); } }); Ti.Android.currentActivity.addEventListener( 'resume' , function (e) { if (accelerometerAdded) { Ti.API.info( "adding accelerometer callback on resume" ); Ti.Accelerometer.addEventListener( 'update' , accelerometerCallback); } }); } |
Summary
In this section, you learned how to add support for shakes, swipes, touches, pinches, and long presses. You even explored how you can use the accelerometer as a means of user input. Finally, you handled global events within the app's lifecycle to manage battery drain.