Displaying HTML content in mobile apps
The
StageWebView
class displays HTML content using the system browser control on mobile devices
and using the standard Adobe® AIR® HTMLLoader control on desktop computers.
Check the StageWebView.isSupported
property to determine whether the class is
supported on the current device. Support is not guaranteed for all devices in
the mobile profile.
In all profiles, the StageWebView class supports only limited interaction between the HTML content and the rest of the application. You can control navigation, but no cross-scripting or direct exchange of data is allowed. You can load content from a local or remote URL or pass in a string of HTML.
StageWebView objects
A StageWebView object is not a display object and cannot be added to the display list. Instead, it operates as a viewport attached directly to the stage. StageWebView content draws over the top of any display list content. There is no way to control the drawing order of multiple StageWebView objects.
To display a StageWebView object, you assign the stage on which the object is to
appear to the stage
property of the StageWebView. Set the size of the display
using the viewPort
property.
Set the x and y coordinates of the viewPort
property between -8192 and 8191.
The maximum value of stage width and height is 8191. If the size exceeds the
maximum values, an exception is thrown.
The following example creates a StageWebView object, sets the stage
and
viewPort
properties, and displays a string of HTML:
var webView:StageWebView = new StageWebView();
webView.viewPort = new Rectangle( 0, 0, this.stage.stageWidth, this .stage.stageHeight);
webView.stage = this.stage;
var htmlString:String = "<!DOCTYPE HTML>" +
"<html><body>" +
"<p>King Philip could order five good steaks.</p>" +
"</body></html>";
webView.loadString( htmlString );
To hide a StageWebView object, set its stage
property to null
. To destroy
the object entirely, call the dispose()
method. Calling dispose()
is
optional, but does help the garbage collector reclaim the memory used by the
object sooner.
Content
You can load content into a StageWebView object using two methods: loadURL()
and loadString()
.
The loadURL()
method loads a resource at the specified URL. You can use any
URI scheme supported by the system web browser control, including: data:, file:,
http:, https:, and javascript:. The app: and app-storage: schemes are not
supported. AIR does not validate the URL string.
The loadString()
method loads a literal string containing HTML content. The
location of a page loaded with this method is expressed as:
On Desktop: about:blank
On iOS: htmlString
On Android: the data URI format of the encoded htmlString
The URI scheme determines the rules for loading embedded content or data.
URI scheme | Load local resource | Load remote resource | Local XMLHttpRequest | Remote XMLHttpRequest |
---|---|---|---|---|
data: | No | Yes | No | No |
file: | Yes | Yes | Yes | Yes |
http:, https: | No | Yes | No | Same domain |
about: (loadString() method) | No | Yes | No | No |
Note: If the stage's displayState
property is set to FULL_SCREEN
, in
Desktop, you cannot type in a text field displayed in the StageWebView. However,
in iOS and Android, you can type in a text field on StageWebView even if the
stage's displayState
is FULL_SCREEN
.
The following example uses a StageWebView object to display Adobe's website:
package
{
import flash.display.MovieClip;
import flash.media.StageWebView;
import flash.geom.Rectangle;
public class StageWebViewExample extends MovieClip
{
public var webView:StageWebView = new StageWebView();
public function StageWebViewExample()
{
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
webView.loadURL( "http://www.adobe.com" );
}
}
}
On Android devices, you must specify the Android INTERNET permission in order for the app to successfully load remote resources.
In Android 3.0+, an application must enable hardware acceleration in the Android manifestAdditions element of the AIR application descriptor to display plug-in content in a StageWebView object. See Enabling Flash Player and other plug-ins in a StageWebView object.
JavaScript URI
You can use a JavaScript URI to call a function defined in the HTML page that is loaded by a StageWebView object. The function you call using the JavaScript URI runs in the context of the loaded web page. The following example uses a StageWebView object to call a JavaScript function:
package
{
import flash.display.*;
import flash.geom.Rectangle;
import flash.media.StageWebView;
public class WebView extends Sprite
{
public var webView:StageWebView = new StageWebView();
public function WebView()
{
var htmlString:String = "<!DOCTYPE HTML>" +
"<html><script type=text/javascript>" +
"function callURI(){" +
"alert(\"You clicked me!!\");"+
"}</script><body>" +
"<p><a href=javascript:callURI()>Click Me</a></p>" +
"</body></html>";
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
webView.loadString( htmlString );
}
}
}
Navigation events
When a user clicks a link in the HTML, the StageWebView object dispatches a
locationChanging
event. You can call the preventDefault()
method of the
event object to stop the navigation. Otherwise, the StageWebView object
navigates to the new page and dispatches a locationChange
event. When the page
load has finished, the StageWebView dispatches a complete
event.
A locationChanging
event is dispatched on every HTML redirect. The
locationChange
and complete
events are dispatched at the appropriate time.
On iOS, a locationChanging
event is dispatched before a locationChange
event, except for the first loadURL(
) or l oadString()
methods. A
locationChange
event is also dispatched for navigational changes through
iFrames and Frames.
The following example illustrates how you can prevent a location change and open the new page in the system browser instead.
package
{
import flash.display.MovieClip;
import flash.media.StageWebView;
import flash.events.LocationChangeEvent;
import flash.geom.Rectangle;
import flash.net.navigateToURL;
import flash.net.URLRequest;
public class StageWebViewNavEvents extends MovieClip
{
var webView:StageWebView = new StageWebView();
public function StageWebViewNavEvents()
{
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
webView.addEventListener( LocationChangeEvent.LOCATION_CHANGING, onLocationChanging );
webView.loadURL( "http://www.adobe.com" );
}
private function onLocationChanging( event:LocationChangeEvent ):void
{
event.preventDefault();
navigateToURL( new URLRequest( event.location ) );
}
}
}
History
As a user clicks links in the content displayed in a StageWebView object, the control saves the backwards and forwards history stacks. The following example illustrates how to navigate through the two history stacks. The example uses the Back and Search soft keys.
package
{
import flash.display.MovieClip;
import flash.media.StageWebView;
import flash.geom.Rectangle;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class StageWebViewExample extends MovieClip
{
var webView:StageWebView = new StageWebView();
public function StageWebViewExample()
{
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight );
webView.loadURL( "http://www.adobe.com" );
stage.addEventListener( KeyboardEvent.KEY_DOWN, onKey );
}
private function onKey( event:KeyboardEvent ):void
{
if( event.keyCode == Keyboard.BACK && webView.isHistoryBackEnabled )
{
trace("back");
webView.historyBack();
event.preventDefault();
}
if( event.keyCode == Keyboard.SEARCH && webView.isHistoryForwardEnabled )
{
trace("forward");
webView.historyForward();
}
}
}
}
Focus
Even though it is not a display object, the StageWebView class contains members that allow you to manage the focus transitions into and out of the control.
When the StageWebView object gains focus, it dispatches a focusIn
event. You
use this event to manage the focus elements in your application, if necessary.
When the StageWebView relinquishes the focus, it dispatches a focusOut
event.
A StageWebView instance can relinquish focus when a user "tabs" past the first
or last control on the web page using a device trackball or directional arrows.
The direction
property of the event object lets you know whether the focus
flow is rising up past the top of the page or down through the bottom of the
page. Use this information to assign focus to the appropriate display object
above or below the StageWebView.
On iOS, focus cannot be set programmatically. StageWebView dispatches focusIn
and focusOut
events with the direction property of FocusEvent
set to none
.
If the user touches inside the StageWebView, the focusIn
event is dispatched.
If the user touches outside the StageWebView, the focusOut
event is
dispatched.
The following example illustrates how focus passes from the StageWebView object to Flash display objects:
package
{
import flash.display.MovieClip;
import flash.media.StageWebView;
import flash.geom.Rectangle;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.events.FocusEvent;
import flash.display.FocusDirection;
import flash.events.LocationChangeEvent;
public class StageWebViewFocusEvents extends MovieClip
{
var webView:StageWebView = new StageWebView();
var topControl:TextField = new TextField();
var bottomControl:TextField = new TextField();
public function StageWebViewFocusEvents()
{
trace("Starting");
topControl.type = TextFieldType.INPUT;
addChild( topControl );
topControl.height = 60;
topControl.width = stage.stageWidth;
topControl.background = true;
topControl.text = "One control on top.";
topControl.addEventListener( FocusEvent.FOCUS_IN, flashFocusIn );
topControl.addEventListener( FocusEvent.FOCUS_OUT, flashFocusOut );
webView.stage = this.stage;
webView.viewPort = new Rectangle( 0, 60, stage.stageWidth, stage.stageHeight
- 120 );
webView.addEventListener( FocusEvent.FOCUS_IN, webFocusIn );
webView.addEventListener(FocusEvent.FOCUS_OUT, webFocusOut );
webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING,
function( event:LocationChangeEvent ):void
{
event.preventDefault();
} );
webView.loadString("<form action='#'><input/><input/><input/></form>");
webView.assignFocus();
bottomControl.type = TextFieldType.INPUT;
addChild( bottomControl );
bottomControl.y = stage.stageHeight - 60;
bottomControl.height = 60;
bottomControl.width = stage.stageWidth;
bottomControl.background = true;
bottomControl.text = "One control on the bottom.";
bottomControl.addEventListener( FocusEvent.FOCUS_IN, flashFocusIn );
bottomControl.addEventListener( FocusEvent.FOCUS_OUT, flashFocusOut );
}
private function webFocusIn( event:FocusEvent ):void
{
trace("Web focus in");
}
private function webFocusOut( event:FocusEvent ):void
{
trace("Web focus out: " + event.direction);
if( event.direction == FocusDirection.TOP )
{
stage.focus = topControl;
}
else
{
stage.focus = bottomControl;
}
}
private function flashFocusIn( event:FocusEvent ):void
{
trace("Flash focus in");
var textfield:TextField = event.target as TextField;
textfield.backgroundColor = 0xff5566;
}
private function flashFocusOut( event:FocusEvent ):void
{
trace("Flash focus out");
var textfield:TextField = event.target as TextField;
textfield.backgroundColor = 0xffffff;
}
}
}
Bitmap capture
A StageWebView object is rendered above all display list content. You cannot add a content above a StageWebView object. For example, you cannot expand a drop-down over the StageWebView content. To solve this issue, capture a snapshot of the StageWebView. Then, hide the StageWebView and add the bitmap snapshot instead.
The following example illustrates how to capture the snapshot of a StageWebView
object using the drawViewPortToBitmapData
method. It hides the StageWebView
object by setting the stage to null. After the web page is fully loaded, it
calls a function that captures the bitmap and displays it. When you run, the
code displays two labels, Google and Facebook. Clicking the label captures the
corresponding web page and displays it as a snapshot on the stage.
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.*;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.net.*;
import flash.text.TextField;
public class stagewebview extends Sprite
{
public var webView:StageWebView=new StageWebView();
public var textGoogle:TextField=new TextField();
public var textFacebook:TextField=new TextField();
public function stagewebview()
{
textGoogle.htmlText="<b>Google</b>";
textGoogle.x=300;
textGoogle.y=-80;
addChild(textGoogle);
textFacebook.htmlText="<b>Facebook</b>";
textFacebook.x=0;
textFacebook.y=-80;
addChild(textFacebook);
textGoogle.addEventListener(MouseEvent.CLICK,goGoogle);
textFacebook.addEventListener(MouseEvent.CLICK,goFaceBook);
webView.stage = this.stage;
webView.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
}
public function goGoogle(e:Event):void
{
webView.loadURL("http://www.google.com");
webView.stage = null;
webView.addEventListener(Event.COMPLETE,handleLoad);
}
public function goFaceBook(e:Event):void
{
webView.loadURL("http://www.facebook.com");
webView.stage = null;
webView.addEventListener(Event.COMPLETE,handleLoad);
}
public function handleLoad(e:Event):void
{
var bitmapData:BitmapData = new BitmapData(webView.viewPort.width, webView.viewPort.height);
webView.drawViewPortToBitmapData(bitmapData);
var webViewBitmap:Bitmap=new Bitmap(bitmapData);
addChild(webViewBitmap);
}
}
}
Adobe recommends
AIR2.5 StageWebView demo – OAuth Support
Evangelist Mark Doherty demonstrates how to log in to an OAuth protected site like Twitter using the StageWebView class.
Making the most of StageWebView
Sean Voisen
HTML Web View in Air for Android
Jonathan Campos
Create a basic web browser with StageWebView
Rich Tretola
AIR Mobile StageWebView UIComponent
Sönke Rohde
Using StageWebView within a UIComponent in Mobile
Judah Frangipane