One of the navigation methods unique to mobile devices is the ability to interact with an application via gestures on the device’s touchscreen. Multitouch is defined as the ability to simultaneously register three or more touch points on the device. Within Adobe AIR 2.6, there are two event classes used to listen for multitouch events.
The GestureEvent
class is used to listen for a
two-finger tap on the device. The event used to listen for this action
is GESTURE_TWO_FINGER_TAP
. This event
will return the registration points for the x and y coordinates when a
two-finger tap occurs for both stage positioning as well as object
positioning.
Let’s review the code below. Within
applicationComplete
of the application, an event
handler function is called, which first
sets the Multitouch.inputMode
to Multitouch
InputMode.GESTURE
. Next, it checks to see
if the device supports multitouch by reading the static property of the
Multitouch
class. If this property returns as true,
an event listener is added to the stage to listen for GestureEvent.GESTURE_TWO_FINGER_TAP
events.
When this event occurs, the onGestureTwoFinderTap
method is called., which will capture the localX
and
localY
coordinates as well as the
stageX
and stageY
coordinates. If
you two-finger-tap on an empty portion of the stage, these values will
be identical. If you
two-finger-tap on an object on the stage, the
localX
and localY
coordinates will
be the values within the object, and the stageX
and
stageY
will be relative to the stage itself. See
Figure 4-9 for an example of a
two-finger tap on the stage and Figure 4-10 for a two-finger tap on the
Android image:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationComplete="application1_applicationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protectedfunction application1_applicationCompleteHandler (event:FlexEvent):void { Multitouch.inputMode = MultitouchInputMode.GESTURE; if(Multitouch.supportsGestureEvents){ stage.addEventListener(GestureEvent.GESTURE_TWO_FINGER_TAP, onGestureTwoFingerTap); } else { status.text="gestures not supported"; } } privatefunction onGestureTwoFingerTap(event:GestureEvent):void { info.text = "event = " + event.type + "\n" + "localX = " + event.localX + "\n" + "localX = " + event.localY + "\n" + "stageX = " + event.stageX + "\n" + "stageY = " + event.stageY; } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <s:Label id="status" text="Do a 2 finger tap both on and off the object" top="10" width="100%" textAlign="center"/> <s:TextArea id="info" width="100%" top="40" editable="false"/> <s:Image width="384" height="384" bottom="10" horizontalCenter="0" source="@Embed('android_icon.png')"/> </s:Application>
There are multiple transform gesture events available within AIR
2.6. Each will capture a unique multitouch event. The example below
demonstrates how to listen for GESTURE_PAN
, GESTURE_ROTATE
, GESTURE_SWIPE
, and GESTURE_ZOOM
events.
Let’s review the code below. Within
applicationComplete
of the application, an event
handler function is called, which first
sets the Multitouch.inputMode
to Multitouch
InputMode.GESTURE
. Next, it checks to see
if the device supports multitouch by reading the static property of the
Multitouch
class. If this property returns as true,
event listeners are added to the stage to listen for the TransformGestureEvent.GESTURE_PAN
, TransformGestureEvent.GESTURE_ROTATE
, TransformGestureEvent.GESTURE_SWIPE
, and
TransformGestureEvent.GESTURE_ZOOM
events.
When a user grabs an object with two
fingers and drags it, the TransformGesture
Event.GESTURE_PAN
event
is triggered and the onGesturePan
method is called.
Within the onGesturePan
method, the
offsetX
and offsetY
values of this
event are written to the text
property of the
TextArea
component. Adding the event’s
offsetX
and offsetY
values sets the object’s
x and y to move the object
across the stage. The results can be seen in Figure 4-11.
When a user grabs an object with two
fingers and rotates it, the TransformGesture
Event.GESTURE_ROTATE
event is triggered and the onGestureRotate
method is
called. Within the onGestureRotate
method, the
rotation value of this event is written to the text
property of the TextArea component.
To allow the object to rotate around its center, the object’s
transformAround
method is called and the event’s
rotation value is added to the object’s rotationZ
value. The results can be seen in Figure 4-12.
When a user swipes across an object with one finger in any
direction, the TransformGestureEvent.GESTURE_SWIPE
event is
triggered and the onGestureSwipe
method is called.
Within the onGestureSwipe
method, the values of the
event’s offsetX
and offsetY
are
evaluated to determine the direction in which the user swiped across the
object. This direction is then written to the text
property of the TextArea
component. The results can
be seen in Figure 4-13.
When a user performs a “pinch and zoom” action with two fingers on
an object, the TransformGestureEvent.GESTURE_ZOOM
event is
triggered and the onGestureZoom
method is called.
Within the onGestureZoom
method, the values of the
event’s scaleX
and scaleY
are written to the
text
property of the TextArea
component. The scaleX
value is then used as a
multiplier on the object’s scaleX
and
scaleY
property to increase or decrease the size of
the object as the user pinches or expands two fingers on the object. The
results can be seen in Figure 4-14:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationComplete="application1_applicationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protectedfunction application1_applicationCompleteHandler (event:FlexEvent):void { Multitouch.inputMode = MultitouchInputMode.GESTURE; if(Multitouch.supportsGestureEvents){ image.addEventListener(TransformGestureEvent.GESTURE_PAN, onGesturePan); image.addEventListener(TransformGestureEvent.GESTURE_ROTATE, onGestureRotate); image.addEventListener(TransformGestureEvent.GESTURE_SWIPE, onGestureSwipe); image.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onGestureZoom); } else { status.text="gestures not supported"; } } privatefunction onGesturePan(event:TransformGestureEvent):void{ info.text = "event = " + event.type + "\n" + "offsetX = " + event.offsetX + "\n" + "offsetY = " + event.offsetY; image.x += event.offsetX; image.y += event.offsetY; } privatefunction onGestureRotate( event : TransformGestureEvent ) : void { info.text = "event = " + event.type + "\n" + "rotation = " + event.rotation; image.transformAround(new Vector3D(image.width/2, image.height/2, 0), null, new Vector3D(0,0,image.rotationZ + event.rotation)); } privatefunction onGestureSwipe( event : TransformGestureEvent ) : void { var direction:String = ""; if(event.offsetX == 1) direction = "right"; if(event.offsetX == −1) direction = "left"; if(event.offsetY == 1) direction = "down"; if(event.offsetY == −1) direction = "up"; info.text = "event = " + event.type + "\n" + "direction = " + direction; } privatefunction onGestureZoom( event : TransformGestureEvent ) : void { info.text = "event = " + event.type + "\n" + "scaleX = " + event.scaleX + "\n" + "scaleY = " + event.scaleY; image.scaleX = image.scaleY *= event.scaleX; } protectedfunction button1_clickHandler(event:MouseEvent):void { image.rotation = 0; image.scaleX = 1; image.scaleY = 1; image.x = 40; image.y = 260; info.text = ""; } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <s:Label id="status" text="Transform Gestures" top="10" width="100%" textAlign="center"/> <s:HGroup width="100%" top="40" left="5" right="5"> <s:TextArea id="info" editable="false" width="100%" height="200"/> <s:Button label="Reset" click="button1_clickHandler(event)"/> </s:HGroup> <s:Image id="image" x="40" y="260" width="400" height="400" source="@Embed('android_icon.png')"/> </s:Application>
Get Developing Android Applications with Flex 4.5 now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.