I’m working on a simple Flex mobile app to test out the viability of it as a cross-platform mobile development environment/sdk. This app is a simple master/detail view-based application [based on s:ViewNavigatorApplication]: show a list of items, select an item, see details. That’s it. On the details view there was an issue with displaying the item content so I just used HTML [since that’s what the source data is on occasions]. This was easy enough, after a lil’ googling, with the StageWebView but there were some gotchas.
Before the gotchas, let’s look at how the StageWebView [SWV from here on out] works.
- Highest Item Visible
This was understandable seeing as StageVideo handles it the same way. The SWV sits on top of everything else so you have to size it differently than normal. In other words, it isn’t part of the display stack we, ActionScript developers, are used to working with. - View Independence
You can pop your views on/off the view stack all day and the SWV will still be visible regardless of what view created it. You may not be able to programmatically access it, if you’ve popped the view with the reference to it, but it will be visible. It is easiest to think of it as a native, modal window on top of your application.
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true); ... protected function onKeyDown(event:KeyboardEvent):void{ if(event.keyCode == Keyboard.BACK && swv){ swv.viewPort = null; swv.dispose(); swv = null; navigator.popToFirstView(); } } |
Nothing major. Just listen for the back button key press, null the viewPort, dispose of the swv instance, null the swf instance [garbage collection “trick”], pop the current details view, and push the first view on the stack. It worked…sort of. The SWV instance would be disposed of but my first view would not show. Instead I would see a blank view.
Come to find out, view-based applications automatically handle the back button press, essentially managing the view stack itself, so by me popping the view AND the ViewNavigatorApplication natively doing so as well, I was popping the view twice. To fix this, Jason San Jose suggested I prevent the default event from occurring so I added event.preventDefault(); right after the if statement above. This worked but he told me about FlexEvent.BACK_KEY_PRESSED and I found out s:View dispatches it so my code then turned into:
<s:View xmlns:fx="https://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="" actionBarVisible="true" creationComplete="init(event)" backKeyPressed="onBackKeyPressed(event)"> <fx:Script> <![CDATA[ ... protected function onBackKeyPressed(event:FlexEvent):void{ swv.viewPort = null; swv.dispose(); swv = null; } ]]> </fx:Script> ... </s:View> |
Now I don’t need to sweat removing event listeners from the stage or hoping they get properly removed if I mark them weak, etc.
I’ll most likely remove this code from the event handler and put it in a more specific function [like removeSWV()] so I can add a button in my UI for iOS to trigger the removal of the SWV and pop the view from the stack.
I hope this helps. Sound off in the comments if you have other ways of resolving this situation or thoughts on the StageWebView in general.