SebastianT
SebastianT

Reputation: 283

Flex Mobile: preventing back button from exiting app

I'm developing a Flex Mobile application for some android tablet and until now I've been unable to prevent the Back Button from leaving the application. I still want it's regular functionality, it's just that I don't want it to exit the app. I want the user to do this manually.

Any ideas on how to achieve this? Maybe by catching some event? Any help will be greatly appreciated.

Regards,

Sebastián

Upvotes: 0

Views: 1882

Answers (3)

SebastianT
SebastianT

Reputation: 283

The only code needed to solve this issue is the following:

<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                            xmlns:s="library://ns.adobe.com/flex/spark">

...

      <fx:Script>
        <![CDATA[

                   ...

            /**
             * Overrides the default backKeyUpHandler method so the event 
             * is stopped when there's only one View left on the navigator's stack. 
             */
            override protected function backKeyUpHandler(event:KeyboardEvent):void
            {               
                if (navigator.length == 1){                 
                    event.stopImmediatePropagation();                   
                    event.preventDefault();                 
                }else{
                    super.backKeyUpHandler(event)
                }
            }

        ]]>
    </fx:Script>

</s:ViewNavigatorApplication>

On the View you should have:

<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:componets="componets.*"       
        viewActivate="addKeyListeners(event)"
        viewDeactivate="removeKeyListeners(event)">

...
        <fx:Script>
        <![CDATA[
                          ...
            /**
             * Stops the Back key event.
             */
            private function keyDown(event:KeyboardEvent):void
            {               
                if(event.keyCode == Keyboard.BACK)
                {
                    event.stopImmediatePropagation();                   
                    event.preventDefault();                 
                }
            }
       ]]>
    </fx:Script>

</s:View>

Thanks Alexander and Josh for your help.

Regards,

Sebastián

Upvotes: 1

Alexander Farber
Alexander Farber

Reputation: 23038

Here is how I handle it:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark"
        initialize="init()"
        viewActivate="activate(event)"
        viewDeactivate="deactivate(event)">

<fx:Declarations>
    <fx:Component className="ConfirmExit">
        <s:Callout 
            horizontalPosition="middle"
            verticalPosition="middle">
            <s:VGroup width="100%">

                <s:Label text="Really quit?" />

                <s:HGroup width="100%">

                    <s:Button label="Yes"
                              click="close(true)" />
                    <s:Button label="No"
                              click="close(false)" />
                </s:HGroup>
            </s:VGroup>
        </s:Callout>        
    </fx:Component>
</fx:Declarations>

<fx:Script>
    <![CDATA[
        import spark.events.ViewNavigatorEvent;

        private function activate(event:ViewNavigatorEvent):void {
            // add exit confirmation dialog - Samsung Apps requirement
            if (Capabilities.version.indexOf('AND') >= 0 &&
                Capabilities.manufacturer.search(/Samsung/i) >= 0) {
                _confirmExit.addEventListener(PopUpEvent.CLOSE, handleLeaveCallback, false, 0, true);
                stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp, false, 1, true);
            } 
        }

        private function deactivate(event:ViewNavigatorEvent):void {
            _confirmExit.removeEventListener(PopUpEvent.CLOSE, handleLeaveCallback);
            stage.removeEventListener(KeyboardEvent.KEY_UP, handleKeyUp);
        }

        private function handleKeyUp(event:KeyboardEvent):void {
            if (event.keyCode == Keyboard.BACK /* && navigator.length == 1 */) {
                _confirmExit.open(this, true);
                // event.preventDefault();
            }
        }

        private function handleLeaveCallback(event:PopUpEvent):void {
            if (!event.commit)
                return;

            try {
                NativeApplication.nativeApplication.exit();
            } catch (e:Error) {
            }
        }

I.e. don't call any base class methods and use the priority of 1 here:

stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp, false, 1, true);

Upvotes: 1

Josh
Josh

Reputation: 8159

The ViewNavigator will exit the app if there are no more views to pop. You can see how many views are currently being managed by it using ViewNavigator.length. So, theoretically, something like this should work:

stage.addEventListener( KeyboardEvent.KEY_UP, backButtonHandler );

private function backButtonHandler( e:KeyboardEvent ):void {
    if ( e.charCode == Keyboard.BACK && this.navigator.length == 1 ) {
        e.stopImmediatePropagation();
    }
}

Now, that is untested. I believe it should work, however. You may need to check if the length is equal to 0 instead of 1; I'm unsure if the current view counts against the length off the top of my head. That should prevent the back button from running any operation when there are no more views to pop, however.

Upvotes: 0

Related Questions