Using StageWebView within a UIComponent in Mobile

StageWebView is the name given to the class that displays the native browser of a mobile device in your mobile app. Since it’s not actually native to AIR it floats above your app. This is a nice gift from the AIR team but as it is you must manually size, position and control the visibility. Well not anymore!

The WebView class adds those features. It wraps the StageWebView up in a UIComponent wrapper. This allows it to be sized, positioned and so on like any other Flex component.

It also exposes the StageWebView snapshot feature. This is a flag that when set to true displays captures snapshot of the Stage Web View at the time the property is set. It then hides the actual StageWebView instance. Setting this property to false removes the snapshot and displays the live web view again. This allows you to display Flex components on top of the web view snapshot. It also helps you to integrate the web view into the display list for animations, transitions, etc.

All updates
• June 2011 – I’ve made a complete rewrite of it. This release exposes the rest of the StageWebView methods and properties and adds snapshot mode and HTML content wrapping.
• July 2011 – I’ve added a few bug fixes and implemented commit properties and measure. Added properties for keyCode for history back and forward. Webview maintains state. Key navigation can be disabled properly. This version is not as tested as much as the last. Let me know of any issues. July 28 release (early release)
• Nov 2011 – Feel free to modify and post this or derivatives on your own site.
• Dec 2011 – I’ve been working on an update. The first thing I’ve fixed is that webview visibility is bound to the UIComponent visible property instead of the developer manually hiding and showing it.
• Jan 2012 – Created a mobile example project showing loading a local URL, remote URL, HTML markup, HTML page markup and snapshot mode.
• Feb 2012 – I’ve uploaded the class and example to my Google Code mobile library.
• Jan 2012 – LATEST STABLE – This is the latest stable download for Jan 2012 Release and Example Project
• Feb 2013 – LATEST BETA – A new beta version that supports runtime DPI and adds more support for JavaScript is available in the GitHub repository here. I’ve added StyleableWebView that has some usage examples. I haven’t had time to create a zip or example project for the this version but it’s being used in production. To use this you can manually download the class files you need from GitHub or you will have to checkout the MainLibrary and MobileLibrary projects from GitHub and then import those into FlashBuilder to create the SWC. Once you’ve added the SWC to your own project you can then create instances of a WebView component.

To use:

<!-- StageWebView is only available for Flex SDK Mobile (Flex 4.5) -->
<?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"
			   xmlns:components="com.flexcapacitor.components.*">

	<fx:Script>
		<![CDATA[
			protected function button1_clickHandler(event:MouseEvent):void {
				event.currentTarget.selected ? webView.loadString("Hello world") : webView.load("http://google.com");
			}

			protected function togglebutton1_clickHandler(event:MouseEvent):void {
				webView.snapshotMode = event.currentTarget.selected;
			}

		]]>
	</fx:Script>

	<s:HGroup>
		<s:ToggleButton label="HTML/URL" click="button1_clickHandler(event)"
						width="150" height="64"/>
		<s:ToggleButton label="Snapshot" click="togglebutton1_clickHandler(event)"
						width="150" height="64"/>
		<s:ToggleButton label="Add/Remove" click="button2_clickHandler(event)"
				  width="150" height="64"/>
	</s:HGroup>

	<components:WebView id="webView" top="100" source="http://google.com" width="100%" height="100%"/>

	<s:Label top="100" width="100%"
			 text="This label is only visible when a non interactive snapshot is being displayed."
			 fontWeight="bold" fontSize="24"
			 backgroundColor="#ffffff" lineBreak="toFit" />
</s:Application>
This entry was posted in AIR, Flash, Flex, Mobile, Tips. Bookmark the permalink.

149 Responses to Using StageWebView within a UIComponent in Mobile

  1. koidy says:

    it there any methods put other components upon the webView?

    • Judah says:

      The StageWebView is at this time always going to be the top most component in your application but you can take a screenshot of the stage web view, then hide the instance of the stage web view and show the image snapshot you just created in it’s place and with that image showing and the actual stage web view hidden then layer Flex components on top of that.

      • Judah says:

        There are new snapshot features that allow you to go into snapshot mode. Once in that mode other components can overlay the component.

  2. brybam says:

    should this still work in the newest prerelease? I keep getting a “Flex Problem” saying
    Could not resolve to a component implementation.

  3. Raul Jimenez says:

    Hi,

    With the last build it throws a runtime error, I just fixed it with this change.

    public function addedToStageHandler(event:Event):void
    {
    if (webView) webView.stage = stage;
    invalidateDisplayList();
    }

    Nice work!

  4. Jonathan says:

    HELP! I’ve imported it to my project, placing it in a components package but it Flash Builder 4.5 says it can not resolve to a component implementation view.

    If you could help, as I need this component.

    Many Thanks in advance.

    • Judah says:

      Hi Jonathan,
      Is your project a mobile project? This is a mobile only component. BTW I’ve done a rewrite of it and I’ll post it shortly.

  5. Jonathan says:

    Hi

    Sorry, yes it is, to be ouput on as many types as possible.

    Thanks for the reply. I’ll be looking forward to the write.

  6. Jonathan says:

    Well, it’s changed the error! *LOL*

    It now says “Type was not found or was not a compile-time constant: WebView”

    • Judah says:

      Can you post the code you’re using? Wrap the code in XML tags [ xml ] code [ /xml]
      [xml]
      [/xml]

      • Jonathan says:

        The init() function is called on creationComplete in the application tag.

        [actionscript]
        private var admobURL:String = “http://framethis.co.cc/admob.htm”;
        private var webView:StageWebView = new StageWebView();

        protected var radio:AudioPlayer = new AudioPlayer();
        protected var prevVol:Number = 0;

        private function init():void
        {
        webView.stage = this.stage;
        webView.viewPort = new Rectangle(0, 0, 320, 50);
        trace(“init called.”);
        radio.load(“http://uk1-vn.mixstream.net:9928/;”);
        hsliVolume.value = radio.volume;
        webView.loadURL(admobURL);
        }
        [/actionscript]

        • Judah says:

          The class is of type WebView. The code would be something similar to the code below:

          [actionscript]
          private var webView:WebView = new WebView ();

          private function init():void
          {

          trace(“init called.”);
          radio.load(“http://uk1-vn.mixstream.net:9928/;”);
          hsliVolume.value = radio.volume;
          addElement(webView);
          webView.width = 320;
          webView.height = 20;
          webView.loadURL(admobURL);
          }
          [/actionscript]

          I think your project *may* need more support. If you do check out the AIR Mobile forums.

  7. Timothy says:

    I am trying to get the stage to fit the screen of the device. Can anyone help me?

    [xml]

    [/xml]

  8. Dimitri K says:

    There was a bug when using your WebView in a View pushed in Navigator because the component was added to stage before the StageWebView was set, thus the StageWebView.stage was never set.

    My solution was to also set the StageWebView stage in its setter if its stage is null and the component’s stage is not:

    public function set webView(value:StageWebView):void {
    _webView = value;
    if (stage && !_webView.stage) // the _webView stage isn't already set
    {
    _webView.stage=stage;
    }
    }

    It was driving me crazy because otherwise no error was thrown but no html content was displayed..

    Hope you’ll find my fix useful, and thank you for this handy component.

  9. Pingback: Notes to myself | Axelology

  10. John says:

    I am using stageWebView in my mobile app but running into two problems. Hoping someone can help!

    1) I want to load a simple web page with a link for a phone number and a link for email. If I view that page in the browser of my smartphone (Android/HTC/Evo), a click on the phone link launches the native dialer with the number already entered. and a click on the email link launches the default email client with the email address already populated.

    BUT, when I access that very same web page inside my Adobe Air app (using stageWebView), clicking on either link causes a page not found message!!! How do I get stageWebView to properly handle these links as the default browser does?

    2) Whenever my app triggers the soft keyboard to enter data into a text field on a form, after I finish and dismiss the soft keyboard my stageWebView remains resized as it was (automatically) to view the soft keyboard. So it is approx 1/2 of the screen when it should be on the whole screen. And the space where the soft keyboard was displayed is blank. No matter what page I navigate to this situation remains until I force close the app and restart.

    How would I fix this?

    Thanks in advance for any assistance!

    • Judah says:

      Hi John,

      I think that when the webview has focus (because a user pressed the enter or “next” key on the softkeyboard) then when it is closed the deactivate event is not passed on to the Flex application. You can set focusEnabled to false as a workaround. If you can confirm please file a bug at Adobe’s bugbase. Steps to reproduce are place cursor in Flex text field (causes keyboard to show), press next key (moves focus to the webview), press Android back key (keyboard is dismissed but no resize event is fired).

  11. polyGeek says:

    Brilliant solution to allowing overlays of StageWebView. Can’t wait to use this.

  12. Pingback: Weekly Developer Journal : July 17th – July 23rd

  13. First of all, great component! It has made the StageWebView more manageable in my Flex Mobile apps.

    I did run into a problem though, with application scaling.
    I had my applicationDPI set to 160 and I was using the WebView component on a fresh view (constrained to zero on all four sides) and on higher DPI devices, the WebView only took up a portion of the screen. Removing the applicationDPI fixed this, but that can affect the rest of the application as well. Something to look into :)

    Thanks again!

    • Judah says:

      Hi Matt,
      I don’t know the solution but I’ve seen it before and I’ve seen some code in some of the core framework components that check the applicationDPI setting for laying out their content. I’ll check it out but if you get to it first let me know. :)

    • Judah says:

      Matt, I think this may solve it. Replace the update display list with this code:

      		/**
      		 * @copy mx.core.UIComponent#updateDisplayList()
      		 * */
      		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
      			var runtimeDPI:int = FlexGlobals.topLevelApplication.runtimeDPI;
      			var applicationDPI:int = FlexGlobals.topLevelApplication.applicationDPI;
      			var point:Point;
      			var scaledWidth:int;
      			var scaledHeight:int;
      			var scaleFactor:Number;
      			var scaledY:int;
      			
      			
      			// NOTE: IF THE WEBVIEW IS NOT BEING SIZED CORRECTLY 
      			// check if focusEnabled is true. If it is then the soft keyboard may not be dispatching the 
      			// deactivate event because the webview has focus when it is dispatched. set to false
      			// position according to the container rather than the stage
      			if (webView) {
      				point = localToGlobal(new Point());
      				scaleFactor = runtimeDPI / applicationDPI;
      				
      				scaledWidth = width * scaleFactor;
      				scaledHeight = height * scaleFactor;
      				
      				webView.viewPort = new Rectangle(point.x, point.y, scaledWidth, scaledHeight);
      				
      			}
      		}
      • Miel says:

        If you do this you’ll get an error when a snapshot is taken. I solved the error by replacing the takeSnapshot function with the code below. However the snapshot seems scaled, I still need to take a look at that… (ideas are welcome).
        Btw: Judah, thx for the component!

        public function takeSnapshot():BitmapData {
        			destroySnapshot();
        			
        			var runtimeDPI:int = FlexGlobals.topLevelApplication.runtimeDPI;
        			var applicationDPI:int = FlexGlobals.topLevelApplication.applicationDPI;
        			var scaleFactor:Number = runtimeDPI / applicationDPI;			
        			snapshotBitmapData = new BitmapData(unscaledWidth*scaleFactor, unscaledHeight*scaleFactor);
        			webView.drawViewPortToBitmapData(snapshotBitmapData);
        			webViewBitmap = new Bitmap(snapshotBitmapData);
        			addChild(webViewBitmap);
        			hideWebView();
        			isSnapshotVisible = true;
        			
        			return snapshotBitmapData;
        		}
        • Miel says:

          Ok, I solved the scaling issue.
          just inverse scale the resulting bitmap.

          public function takeSnapshot():BitmapData {
          			destroySnapshot();
          			
          			var runtimeDPI:int = FlexGlobals.topLevelApplication.runtimeDPI;
          			var applicationDPI:int = FlexGlobals.topLevelApplication.applicationDPI;
          			var scaleFactor:Number = runtimeDPI / applicationDPI;			
          			snapshotBitmapData = new BitmapData(unscaledWidth*scaleFactor, unscaledHeight*scaleFactor);
          			webView.drawViewPortToBitmapData(snapshotBitmapData);
          			webViewBitmap = new Bitmap(snapshotBitmapData);
          			webViewBitmap.scaleX = 1/scaleFactor;
          			webViewBitmap.scaleY = 1/scaleFactor;
          			addChild(webViewBitmap);
          			hideWebView();
          			isSnapshotVisible = true;
          			
          			return snapshotBitmapData;
          		}
  14. Apinan says:

    I’m facing this issue with StageWebView and need some help…
    http://bugs.adobe.com/jira/browse/SDK-31124

    My project is now stuck..
    Do you have any idea/workaround?
    Thanks for any help..

  15. mark rondina says:

    Judah, great work! I’m working on loading in html links from facebook/twitter user streams. I’d like to have it load it up for a preview. When I use the webview to load it all up, I can’t get any gesture events. Does your modification and extension of the StageWebView allow for gesture events, such as swipe?

    • Judah says:

      The only thing I can think of is to take a snapshot of the webview and catch any gestures in Flash. Then pass those on to the web instance URL with javascript:doSomething() calls. Other than that I don’t know.

  16. Mark McGreevy says:

    Greetings Judah

    Love your WebView class but I am having one problem. I have set up a “locationChanging” listner. When a link or javascript changes the location of the web page the locationChanging event fires, (which is what it is supposted to do), but when I execute event.preventDefault() it fails to stop the navigation in Android. It does works in the emulator. Any suggestions?
    Thank you in advance..

  17. joe says:

    hello judah,
    great work buddy was looking for this ….
    just one thing as i got no clue about coding and such and i made a view page in the flex mobile project and i want to link a html in that view …. can you guide me for the final code to copy and paste and after what i should past it …. this is my code at the moment for the page

    any help of what i should do to make the html page load inside this and not to go out from the app am building …?

    respect

    joe

  18. joe says:

    thanks for your replay judah,
    i found a code to fit and html page inside the view page but not seems to work perfect i would really appreciate your help since you seems expert in the coding stuff….
    the problem am facing with this code is that once i run the app, all seems to work fine but if i rotate the view it get missed up and cover my action bar up and my tabbed buttons down also if go and return it back to the way before also it get missed up ….
    any suggestions?

    this is the code am using …

    <?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"
    		overlayControls="true" title="EVENTS PHOTOGRAPHY"
    		viewActivate="view1_viewActivateHandler(event)"
    		viewDeactivate="removeStageWebViewHandler(event)">
    	<s:layout>
    		<s:BasicLayout/>
    	</s:layout>
    	<fx:Script>
    		<![CDATA[
    			import mx.events.FlexEvent;
    			
    			import spark.events.ViewNavigatorEvent;
    			
    			
    			private var myWebView:StageWebView;
    			
    			
    			/**
    			 * @protected 
    			 * Just add and set site of my StageWebView 
    			 * */
    			protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
    			{
    				myWebView = new StageWebView();
    				myWebView.stage = this.stage;
    				myWebView.loadURL("http://www.mysite.com");
    				myWebView.viewPort = new Rectangle(5,60,stage.stageWidth-10,stage.stageHeight-140);
    			}
    			
    			
    			/** 
    			 * @private
    			 *  
    			 * Just override to re-scale due to auto-orientation project nature
    			 * */
    			override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
    				
    				
    				if (myWebView) {
    					var point:Point = localToGlobal(new Point());
    					myWebView.viewPort = new Rectangle(5,60,stage.stageWidth-10,stage.stageHeight-140);
    				}
    			}	
    			
    			protected function goBackHandler(event:MouseEvent):void
    			{
    				
    				navigator.popToFirstView();
    				
    			}
    			
    			protected function removeStageWebViewHandler(event:ViewNavigatorEvent):void
    			{
    				myWebView.stage = null;
    				// just remove the target and will leave.
    				
    			}
    			
    		]]>
    	</fx:Script>
    	<fx:Declarations>
    		<!-- Place non-visual elements (e.g., services, value objects) here -->
    	</fx:Declarations>
    	<s:actionContent>
    		<s:Button label="BACK TO PHOTOGRAPHY" click="goBackHandler(event)"/>
    	</s:actionContent>
    	<s:Image x="-1" y="2" source="assets/eventsback.jpg"/>
    	
    </s:View> 
  19. Nepol says:

    I can’t make it work, I get this error: Description Resource Path Location Type
    1046: Type was not found or was not a compile-time constant: WebView. Mobile.mxml /Mobile/src line 38 Flex Problem

    Line 38 is:

    Its a fresh Mobile Blank project and I copied the code as it is here. Maybe I imported the .as in a wrong folder? Is in the same as my mobile.mxml

    Thanks a lot!

  20. Nepol says:

    I can’t make it work, I get this error: Description Resource Path Location Type
    1046: Type was not found or was not a compile-time constant: WebView. Mobile.mxml /Mobile/src line 38 Flex Problem

    Line 38 is:

    Its a fresh Mobile Blank project and I copied the code as it is here. Maybe I imported the .as in a wrong folder? Is in the same as my mobile.mxml

    Thanks a lot for your time!

  21. Aditya Ayyagari says:

    Hi Judah,

    I am using your component in my Flex Mobile project but I am seeing an inconsistent behavior on each tablet. On Android, the https://url seems to render well. But on iPad2, it was coming back to user login and then on playbook, it hangs to show an empty white background. What could be the reason?

    regards,
    Aditya

    • Judah says:

      Hi Aditya,

      It looks like I missed your comment. Are you still having issues? Does the latest version solve them?

  22. Huy Vu says:

    It’s very cool. If I want to open HTML file in mobile, how can I do?

  23. Carl Simmons says:

    Hey Judah,

    Nice piece of work, does exactly what I was after (providing a ‘relative’ StageWebView), but there is 2 problems. Firstly, I can’t seem to get the latest code to work inside a View. The webview is going to the sites, but not displaying.

    Second, using the older code (July 28th) the web site appears, but on selecting/focusing on a field element the title bar (of the View) disappears (atleast on the iPad).

    Just wondering, maybe you could help out somehow? Kind of at a loss :P

    Carl

    • Carl Simmons says:

      Okay, I managed to get the new code/WebView displaying by creating it in AS3 then adding it to a Group object. Still have the same problem of the title disappearing when an input field has focus.

      • Carl Simmons says:

        Okay, just to report back, the problem was fixed by setting the application’s matched xml file’s node to pan…

        What was that, 4-5 hours? Jesus.

        • Judah says:

          Hi Carl,
          Just reading this now. Sounded like a pain. What does XML node to pan mean? Maybe I can make a note or create a test. Also, what version of AIR are you using?

          • Judah says:

            Update: I realize you’re talking about the Application Descriptor file and then the keyboard mode behavior and also realizing you mentioned it in the comment below this. :P

            That one’s bit me before too.

  24. Carl Simmons says:

    Ah, sorry, wanted to keep short so didn’t explain very well :P Inside the AppName-app.xml file, there is a node

    <softKeyboardBehavior>

    . Setting the value of this node to

    <softKeyboardBehavior>pan</softKeyboardBehavior> 

    stops the title bar from disappearing when focusing on an input field.

    Version of AIR I’m using is 2.6.

  25. Pingback: Vise http side i Flash Builder Mobile applikasjoner

  26. Robert Marley says:

    Hi, and thanks for publishing. I have used the component as MXML, however when I use loadString(); It doesn’t display anything.

    The var definately has a value, as it was working using the standard StageWebView.

    I am using FlashBuilder 4.5
    Mobile application as ViewNavigatorApplication.

    Any ideas?

    Thanks,
    Robert

    • Robert Marley says:

      sorry, quick addition: I am trying to get it to work in a View inside a ViewNavigatorApplication. Content is being retrieved but the screen remains blank.

      I have tried creating in AS then adding to a Group object as Carl Simmons states, but this has no effect.

      • Judah says:

        Can you try to see if you can get it to work in a blank project? What does the content look like? It may be that webview is not created yet. Can you try calling the loadString later? Also, it checks if the value has <html in it. If it doesn’t it wraps the contents within an html tag. If it does it passes the value without modifying it. In case that’s not it check the visibility.

        Looking at the code, there’s a couple of things I could add to check for these conditions.

        • Robert Marley says:

          Thanks, I got it to work by calling the showWebView() function after calling loadString.

          Works very well, especially when rotating the device as the layout and stage are all taken care of by your component. Thanks again!

  27. Brandon says:

    I have been having a problem with the web view in mobile projects. On the iphone it shows the page really small and you need to pinch to zoom in, but on the Android phone it shows it nice like expected, but it wont scroll. Any ideas on what could be set wrong, or need to be set?

    • Rober Marley says:

      Hi Brandon,
      I have it working great on Android and in iOS with this code (simplified):

      		public var stg:WebView = new WebView();
      			
      		public function init(c:int=0)  :void  {  // called when my view is loaded
      				this.addElement(stg);
      
      			}
      			
      		public function showQuestion(ev:Event=null) :void {
      				
              // I load my content string here, removed for readability
              
      				stg.percentHeight = 100;
      				stg.percentWidth = 100;
      					
      				stg.loadString(qcontent);
      				
      				stg.invalidateDisplayList();
      				stg.showWebView();
           }
      

      I hope that helps .

      • Brandon says:

        Robert,

        When I try to use the July 28 download I get this error:
        A file found in a source-path must have the same package structure ‘views’, as the definition’s package, ‘com.flexcapacitor.controls’. WebView.as

        Without it the older version doesn’t seem to have the properties for that. Its getting pretty annoying since all I want to do is show a google calendar in the agenda mode.

        • Robert Marlley says:

          In your project, right click on the “src” folder and select NEW/Folder and name it “com”. Then add to THAT folder a folder called “flexcapacitor” then add to THAT folder a new folder called “components”.

          FB should display this as
          src / com.flexcapacitor.components

          Put WebView.as in the new components folder.

          • Brandon says:

            Thanks. I did get it working, but it is more of a work around. I’m loading a web page that has the calendar embedded. I had to add the meta tag to the page and for the scrolling in the android I made the height a lot more. Not the best solution but it is working for now.

        • Brandon says:

          Robert,
          I finally got rid of the error. But I still need to test the code on an Android phone. I will let you know if it works out.

          Thanks.
          Brandon

      • Brandon says:

        Still the same result on the iPhone, shows it really small and you have to pinch in to be able to read the text…

      • Brandon says:

        Robert,

        Using the loadString function are you loading a url or an actual web page sting (with etc…). I got the page to scroll, but now when I click on an event it wont open the details. So I was thinking if I can pass the loadString function the whole page code, with the meta tag and iFrame that it may work better, but Ive never tried to pass a string that big and wasn’t sure that was what the function would do.

        Thanks again for your help on this.

  28. Brandon says:

    Thanks for the help. I got it working by passing the string also, works good in both android and iOS.

  29. Gerry Man says:

    Unfortunately this class does not work using flex sdk 4.6 – mobile project.
    I mean: webView.snapshotMode = true;

    • Brandon says:

      I’m not sure about the snapshotmode, or others, but I am using it with the 4.6 mobile project.

      • Gerry Man says:

        Thanks Brandon for your reply.
        The problem is that snapshotmode works perfect on button clicks.
        I mean when the html document is fully loaded. If you use it in an
        Event.COMPLETE handler it does not work as there is a delay concerning the visibility of content. So I had to implement a timer
        function.

        • Brandon says:

          Gerry
          I am using the code Robert posted, the only difference is I added it to in the design mode then I loaded an iframe code into the loadString.

  30. Per Buch Larsen says:

    If you can make visible=”true” and visible=”false” work, it would be great. I am still testing in Flex 4.6 with a String field as input, where I control background and font colors as well as other font characteristics. It looks fine but still I need to test more.
    As visible=”false” does not work, how does I initially hide your component? – later I will make it visible in AS code. Do I need to instantiate it in AS instead?

    • Per Buch Larsen says:

      Sorry – I did find the solution replacing the visible option; I shall instead use the functions: hideWebView() and showWebView(). Am I right?

      • Judah says:

        That’s right. I may update the component to support 4.6 over the break. If you feel there should be any changes or updates let me know.

        • Per Buch Larsen says:

          There seems to be no problems using WebView in Flash Builder 4.6.
          I would like to use snapshotmode but then I cannot scroll anymore. Is it possible to change that?

          • Judah says:

            Snapshot mode takes a picture of the webview contents. It’s not live. Unless you mean something else? If you mean what I think then you might be able to expand the webview as high as it goes, put it into snapshot mode and then put that in a Scroller (or enable a parent Scroller). You’d then be able to scroll through the content (non-interactive of course).

      • Judah says:

        I’m testing a version now that causes the webview to be bound to the value of the visible property. In other words visibility works just like any other UIComponent binding and all.

  31. Roland Polzer says:

    I also need features of StageWebViewBridge (e.g. call Javascript and setting transparent background)

    http://code.google.com/p/stagewebviewbridge/

    It would be great if these two were compatible

    • Judah says:

      If you can get in touch with the owner of that project he’s welcome to integrate WebView or create his own version. I’m not sure I could do the same with the time I have.

  32. Roland Polzer says:

    What would be the best way to calloutContent appear completely above a WebView? Right now parts of it are covered by the StageWebView. It would be a nice feature of WebView to automatically take a snapshot and display it instead the StageWebView while it is partially covered. Or is it already supposed to work like this already?

    • Roland Polzer says:

      a) should have used a grammar checker and b) am using snapshotMode now

    • Judah says:

      If the PopUpManager has an event when new pop ups are added or removed then we can listen for them and turn snapshot mode on or off if needed. I’ll see if it’s possible to add this.

  33. Per Buch Larsen says:

    As I am close to end the development of my new iPhone / iPad application developed with Flash Builder 4.6, I can tell, that I have included you browser sucessfully to show external documents and vidoes.
    Now I come to my final question in this turn. I can also make a StageWebView solution show documents that are saved in the data folder structure of my solution but I do not succeed making images visible. Anyway, I cannot show internally saved documents in Safari at all, so it is a kind of progress that I can show the text document – but I would really love to make the images visible, too.
    Is there any solution I might have overlooked?

  34. Per Buch Larsen says:

    I forgot to tell that my images are also storeb internally but in the images folder structure.

  35. Judah says:

    I’ve had issues with the cursor and the focused item. I have a mobile application that has a Text Input used for searching. Below the search TextInput is the WebView. When I set the source of the WebView using loadURL() (setting the source) the key input is shifted to the StageWebView and the Text Input stops receiving key events. Unless there’s another way to handle it you need to set the visibility of the stage web view to true before the user puts the cursor in the Flex text input because as it is the stage web view seems to take it away when it is made visible.

  36. David Malikyar says:

    I’m using the 7/28 WebView but I have the same problem regardless of version. I dropped the WebView on a view. When I run the code in the emulator, it displays the webpage or embedded string but only uses 50% of the component’s height and width. Do I need to set any additional property so it uses the full width and height of the component?

    <?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"
    		xmlns:components="com.flexcapacitor.components.*"
    		xmlns:controls="com.flexcapacitor.controls.*"
    		title="Tab1">
    	<fx:Script>
    		<![CDATA[
    			         protected function button1_clickHandler(event:MouseEvent):void {
    				            event.currentTarget.selected ? webView.loadString("Hello <b>world</b> the rain in spain falls mainly on the plains of niagra falls canada not new yorek.") : webView.load("http://google.com");
    			         }
    			         protected function button2_clickHandler(event:MouseEvent):void {
    				            if (owns(webView)) {
    					               removeElement(webView);
    				            }
    				            else {
    					               addElementAt(webView, 0);
    				            }
    			         }
    			         protected function togglebutton1_clickHandler(event:MouseEvent):void {
    				            webView.snapshotMode = event.currentTarget.selected;
    			         }
    		]]>
    	</fx:Script>
    	<s:HGroup>
    		<s:ToggleButton label="HTML/URL" click="button1_clickHandler(event)" width="120" height="64"/>
    		<s:ToggleButton label="Snapshot" click="togglebutton1_clickHandler(event)" width="90" height="64"/>
    		<s:ToggleButton label="Add/Remove" click="button2_clickHandler(event)" width="90" height="64"/>
    	</s:HGroup>
    	<controls:WebView id="webView" top="72" width="100%" height="100%" source="http://www.prokor.com" />
    </s:View>
    • Judah says:

      I’m not sure what the cause is. Can you check the applicationDPI setting? Try setting it to 160. What OS are you testing for?

    • Brandon says:

      I have found that sometimes I need to reset the height and width in order for it to work properly on all my test devices. Something like this:

      myView.load("http://www.google.com");
      myView.height = stage.stageHeight;
      myView.width = stage.stageWidth;
      myView.showWebView();

      • David Malikyar says:

        Brandon, what event are you setting those properties and calling those methods? If I try to do so in an init() function associated with the creationComplete event, I get an error indicating that stage is null.

        • Brandon says:

          Mine is in the creationcomplete for the web view component.

          • David Malikyar says:

            I’m getting a null object error for stage. Can you see anything that’s off?

            <?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"
            		xmlns:components="com.flexcapacitor.components.*"
            		xmlns:controls="com.flexcapacitor.controls.*"
            		
            		title="Tab1">
            	<fx:Script>
            		<![CDATA[
            			//import com.flexcapacitor.controls.WebView;
            			//private var webView:WebView = new WebView();
            			private function initView():void
            			{
            				 //this.addElement(webView);
            				 webView.top = "72"
            				 webView.height = this.stage.stageHeight;
            				 webView.width = this.stage.stageWidth;
            				 webView.load("http://wwww.google.com");
            				 webView.showWebView();
            			}
            	        protected function button1_clickHandler(event:MouseEvent):void {
            		            event.currentTarget.selected ? webView.loadString("Hello <b>world</b> the rain in spain falls mainly on the plains of niagra falls canada not new yorek.") : webView.load("http://google.com");
            	        }
            	        protected function button2_clickHandler(event:MouseEvent):void {
            		            if (owns(webView)) {
            			               removeElement(webView);
            		            }
            		            else {
            			               addElementAt(webView, 0);
            		            }
            	        }
            	        protected function togglebutton1_clickHandler(event:MouseEvent):void {
            		            webView.snapshotMode = event.currentTarget.selected;
            	        }
            		]]>
            	</fx:Script>
            	<s:HGroup>
            		<s:ToggleButton label="HTML/URL" click="button1_clickHandler(event)" width="120" height="64"/>
            		<s:ToggleButton label="Snapshot" click="togglebutton1_clickHandler(event)" width="90" height="64"/>
            		<s:ToggleButton label="Add/Remove" click="button2_clickHandler(event)" width="90" height="64"/>
            	</s:HGroup>
            	<controls:WebView id="webView" creationComplete="initView()" />
            </s:View>
            • Brandon says:

              Have you tried it without the this. and just using stage.stageHeight?
              Thats the only thing I can see right now. What version of Flash Builder are you using?

        • Judah says:

          David – I created a new version with examples. You shouldn’t have to call showWebView() anymore.

  37. Brandon says:

    Have you tried it without the this. and just using stage.stageHeight?
    Thats the only thing I can see right now. What version of Flash Builder are you using?

    • David Malikyar says:

      My original code did not use “this” but the behavior was the same. I’m using FB 4.6.

      • Brandon says:

        My only other suggestion is to do an oncreationcomplete with the application in the header and see if that helps.

      • Brandon says:

        Just as a thought try using it in a secondary view, not the initial view that comes up and see if that give the stage time to initialize. In my projects I dont have any on the first screen. Like I said, may or may not help, just a thought.

  38. JC Lang says:

    What a great component!
    Thank you man.

  39. Would like to use this code in an open source project under AGPL. What license model you have for the code you publish here?

  40. Trying to use the WebView component as a List item renderer in a mobile AIR project
    (ViewNavigatorApplication) to display rich text field content (HTML), but get no content
    displayed:

    The following is a simplified code extract.

    <code>
    <s:List xmlns:fx="http://ns.adobe.com/mxml/2009" 
    		xmlns:s="library://ns.adobe.com/flex/spark"
    		xmlns:supportClasses="supportClasses.*"
    		<pre class="brush: xml; gutter: false; first-line: 1; highlight: []; html-script: false">

    dataProvider=”{globals.FORMDATA_AC}”
    color=”#000000″
    alternatingItemColors=”[#f2f2f2,#f2f2f2]“>

    I tried using source="http://www.google.com" (instead of content=) to simply open
    a website, but that doesn't work either.

    Any ideas why this is not working?

  41. Sorry, having difficulties to wrap my code…

    <s:List xmlns:fx="http://ns.adobe.com/mxml/2009" 
    		xmlns:s="library://ns.adobe.com/flex/spark"
    		xmlns:supportClasses="supportClasses.*"
    		dataProvider="{globals.FORMDATA_AC}"
    		color="#000000"
    		alternatingItemColors="[#f2f2f2,#f2f2f2]">
    	
    	<s:itemRenderer>				
    		<fx:Component>
    			<s:ItemRenderer cachePolicy="off"
    							fontSize="14" fontWeight="bold"
    							color="#A1925D">
    				
    					<s:VGroup width="100%">		
    						<s:Label width="100%"
    								 text="{data.label}" color="#A1925D"
    								 fontSize="16"/>				
    
    						<supportClasses:WebView id="webView"  
    												width="100%" height="200"
    												autoLoad="true"
    												content="{data.value}"/>
    					</s:VGroup>
    			</s:ItemRenderer>
    		</fx:Component>		
    	</s:itemRenderer>
    </s:List>
    
    • Judah says:

      I’m not sure how well that will work but a couple things to check.
      • Download the latest version posted 1 minute ago

      If that works then you probably will have z-index issues. After you load set your content on the webview set the snapshot mode to true so it joins the display list. You may also need to update the webview again every time data is set and or turn off virtual rows.

  42. Judah says:

    FYI There is a new release and example project posted. Beta of course.

  43. Wow! Fast answer that is :-)

    In the meantime I just solved the problem. I had to make a few changes:

    1)

    the WebView class now extends ItemRenderer (spark). The latter extends UIComponent somewhere down the line

    2)

    I added following setter:

    		public function set viewPort(vwp:Rectangle):void { 
    			 webView.viewPort = vwp; 
    		}
    

    3)

    I changed the updateDisplayList method:

    		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
    			//var point:Point;
    			
    			//point = localToGlobal(new Point());
    			
    			//webView.viewPort = new Rectangle(point.x, point.y, unscaledWidth, unscaledHeight);
    			
    			if (! this.visible)         return;
    			if (! this.includeInLayout) return;
    			if (!webView)               return;
    			
    			var trec:Rectangle = this.owner.getBounds(stage);
    			
    			webView.viewPort = new Rectangle(trec.x+1, trec.y+1, trec.width-1, trec.height-1);
    		}
    

    4)

    I changed the showWebView method:

    public function showWebView():void {
    	if (! webView.stage)
    		webView.stage = stage;
    	else if (webView.stage!=stage) 
    		webView.stage = stage;
    	}
    

    5)

    the List renderer’s WebView component properties include a renderer function and must reside inside a container (e.g. BorderContainer):

    <s:BorderContainer id="webViewContainer"  width="100%" height="200">
    <supportClasses:WebView 
    		id="webView"  
    		color="#000000"
    		contentBackgroundColor="#ffffff"
    		visible="{data.datatype=='HTML'}"
    		includeInLayout="{data.datatype=='HTML'}"
    		render="webView_renderHandler(event)"/>	
    

    6)

    the render_handler changes the viewPort in accordance with the BorderContainers visible bounds:

    protected function webView_renderHandler(event:Event):void
    {
    	// TODO Auto-generated method stub
    	if (data.datatype=='HTML')
    	{
    		var wview:WebView = this.webView;
    					
    		wview.loadString(data.value);
    								
    		var trec:Rectangle = wview.owner.getBounds(stage);
    								
    		wview.viewPort = new Rectangle(trec.x+1, trec.y+1, trec.width-1, trec.height-1);
    
    		wview.showWebView();   // has only an effect if not on stage - see point 4
    	}
    }
    
  44. Dave says:

    Thanks for sharing this Judah! Works like a charm and incorporation time was less than 5 minutes from starting to add code to project to testing on device and having it work.

    You wouldn’t happen to have a workaround that allows you to pull up a decimal pad instead of just the number pad on ios? Would be awesome if you do.

    Thanks again.

    Dave

    • Judah says:

      Thanks Dave. If your text field is in Flex then you can set the softKeyboardType property. If it works on Android but not iOS it might be a bug. On the other hand if your text field is part of your HTML in the WebView I’m not sure what’s available.

  45. ashish says:

    Hello,
    my problem is in my ipad application (using flash builder 4.6) i have added the stagewebview component. i have successfully loaded html page(third party) also.
    when i click on submit button of html page it try to open a pop up (javascript window.open) window but this gets failed in my App and error comes as pop ups are blocked ,please enable the pop up.
    could you please help me .how to enable pop ups in IPad app ??

  46. Carl says:

    Just trying to load up and run the sample project from the WebViewExamples.fxp project (downloaded from the Jan 2012 link, above). Flex shows no designtime errors, and I can validate the project.
    But when I go to Run as Mobile Application, I get the following error:

    Process terminated unexpectedly.

    invalid application descriptor: Unknown namespace: http://ns.adobe.com/air/application/3.1

    Launch command details: “C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.5\sdks\4.5.1\bin\adl.exe” -runtime “C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.5\sdks\4.5.1\runtimes\air\win” -profile mobileDevice -screensize 1280×752:1280×800 -XscreenDPI 150 -XversionPlatform AND “C:\Users\user\Adobe Flash Builder 4.5\WebViewExamples\bin-debug\WebViewExamples-app.xml” “C:\Users\user\Adobe Flash Builder 4.5\WebViewExamples\bin-debug”

    Currently trying to build with the Flex 4.5.1 SDK.
    I’ve tried running as either an Apple iOS device (selecting iPad) or a Google Android device (selecting “Motorola XOOM”), both result in the same error.

    My other projects (not involving WebView) work just fine, and I can instantiate a StageWebView in AS just fine.

    What am I doing wrong?
    -Carl

    • Judah says:

      Hi Carl – The application descriptor file, which is in the root of the project, is specifying that AIR 3.1 is required for this project. It’s in conflict with 4.51. You can change the application descriptor value back to 2.6 and it should work (not sure). Or you can use Flex SDK 4.6 and it should work as well.

  47. Pascal says:

    Hi,

    Great component! Just one question: is it a way to specify a background color when the webview is visible but has not load any content yet?
    Currently it’s white, I would like it to be black.

    Thanks again for sharing this,

    Pascal

    • Judah says:

      I don’t. I’ve noticed it too. I’ve thought about a few work arounds but haven’t tried anything yet. One would be to define html content, which will render quickly, with the background color set in the html. Something like,

      webview.content = "<html><body backgroundColor="#00000"></body></html>";

      Another is to hide the webview and then start loading the content and on url changing or change event set the visibility to true.

  48. Pascal says:

    Judah,

    Seems you are really knowledgeable in Flex. Maybe you could help me on this (out of this topic, I know…)
    http://stackoverflow.com/questions/9208467/flex-mobile-tabbedviewnavigatorapplication-with-tab-on-top-android-style

    Cheers,

    Pascal

  49. Gio says:

    Hi!
    I need to activate the snapshotMode to true when the page is completely loaded.

    Why Event.COMPLETE does not work?


    function completo():void{

    if (objActive.browserSnapshotMode){
    browser.snapshotMode = true
    } else {
    browser.snapshotMode = false
    }
    }
    var browser:WebView = new WebView()
    browser.autoLoad = true
    browser.source =this.browserUrl
    browser.addEventListener(Event.COMPLETE, completo)

    • Judah says:

      Try to listen for the “change” event.

      • Gio says:

        No….
        Debugging on desktop (simulator ipad) Event.COMPLETE works correctly.
        But on ipad, does not work.
        Also Event.CHANGE does not works in ipad.

        Normaly when can’I set the scaleMode?
        Can I set scaleMode before load URL?

        • Judah says:

          The complete event is dispatched when the page has fully loaded. If that isn’t working it may be another issue. The webview doesn’t work completely unless it is on the device. You use the location change events.

          				webview.addEventListener(LocationChangeEvent.LOCATION_CHANGING, locationChangingHandler);
          				webview.addEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangeHandler);

          I’m not aware of the scale mode for the stage web view. Is it a new feature? Taking a guess I would say it’s available after it’s added to the stage.

  50. Gio says:

    One other question….
    I have a s:List with custom itemrender.
    Inside the component I add the WebView.
    But if I move (with scroll) the list I want move also the WebView.

    Can I link (or binding…) the position of WebView to position of one component in snapshotMode = false?

Leave a Reply

Your email address will not be published. Required fields are marked *

Wrap your code before posting! Click the links below:

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">