Emulating the Android long-press interaction

One of the most useful interactions built into the Android operating system is the long press. This is achieved when a user taps a specific area and holds for a few seconds without releasing. While neither Flash Player nor AIR for Android have the long-press interaction as part of the multitouch gesture events library, it is fairly simple to emulate this interaction through either runtime.

How to do it...

We will emulate the Android long-press interaction through use of an ActionScript Timer object along with the use of TouchPoint events.

  1. First, import the following classes into your project:
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;
    import flash.display.Stage;
    import flash.display.Sprite;
    import flash.events.TimerEvent;
    import flash.events.TouchEvent;
    import flash.geom.Rectangle;
    import flash.ui.Multitouch;
    import flash.ui.MultitouchInputMode;
    import flash.utils.Timer;
    
  2. Declare a Sprite object which we will perform the long-press upon, as well as a Timer object:
    private var box:Sprite;
    private var lpTimer:Timer;
    
  3. Set up out Timer object to measure the amount of time it should take to register a long-press; in this case, 1000 milliseconds. Additionally, we will now register a listener to detect when the Timer cycle has completed:
    protected function setupTimer():void {
    lpTimer = new Timer(1000,1);
    lpTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timerEnd);
    }
    
  4. Next, construct a method to handle the creation of our Sprite and add it to the DisplayList:
    protected function setupBox():void {
    box = new Sprite();
    box.graphics.beginFill(0xFFFFFF, 1);
    box.x = stage.stageWidth/2;
    box.y = stage.stageHeight/2;
    box.graphics.drawRect(-100,-100,200,200);
    box.graphics.endFill();
    addChild(box);
    }
    
  5. Set the specific input mode for the multitouch APIs to support touch input by setting Multitouch.inputMode to the MultitouchInputMode.TOUCH_POINT constant. To emulate a long-press, we must start a timer at each instance of a touch interaction through TouchEvent.TOUCH_BEGIN. The Timer will be stopped whenever a TouchEvent.TOUCH_END or some other touch cancelling event is fired, resetting our "long-press".
    protected function setupTouchEvents():void {
    Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
    box.addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin);
    box.addEventListener(TouchEvent.TOUCH_END, touchEnd);
    box.addEventListener(TouchEvent.TOUCH_OUT, touchEnd);
    box.addEventListener(TouchEvent.TOUCH_ROLL_OUT, touchEnd);
    }
    
  6. Construct a method to modify our Sprite upon the start of our touch interaction. We will scale the Sprite slightly and change the alpha property to indicate that something has activated. At this point, we begin measuring the long-press through our Timer:
    protected function touchBegin(e:TouchEvent):void {
    box.scaleX += 0.1;
    box.scaleY += 0.1;
    box.alpha = 0.8;
    lpTimer.start();
    }
    
  7. The Timer is set to complete after 1000 milliseconds, once fired. Upon this trigger, we can then perform whatever action is necessary within the application. In this case, we are making our Sprite dragable:
    protected function timerEnd(e:TimerEvent):void {
    var dragBounds:Rectangle = new Rectangle(box.width/2, box.height/2, stage.stageWidth-box.width, stage.stageHeight-box.height);
    box.startDrag(true, dragBounds);
    }
    
  8. The method for a touch end should stop our Timer and cancel any drag events occurring with our Sprite. Here, we also rest the scale and alpha of our Sprite to return it to a rest state:
    protected function touchEnd(e:TouchEvent):void {
    lpTimer.stop();
    box.stopDrag();
    box.scaleX = 1;
    box.scaleY = 1;
    box.alpha = 1;
    }
    
  9. The resulting gesture will affect our visual object in the following way:

Note

Illustrations provided by Gestureworks (www.gestureworks.com).

How it works...

Our example requires a one second press and hold to trigger a function invocation, which causes a Shape object to become draggable across the Stage. This is accomplished by listening for a TOUCH_BEGIN event, then monitoring a Timer to decide whether this is an intentional long-press interaction. If one second goes by without a TOUCH_END event, then we make the Shape draggable. We have modified the scale and opacity of the Shape once the Timer is triggered to indicate that it now a draggable object. Releasing the Shape will complete the interaction.

There's more...

The most common uses of the long-press are to perform a repositioning of certain visual elements, as we have done here, or to invoke a menu operation as Android users are very comfortable with using this sort of interaction on their devices.