在行動應用程式中顯示 HTML 內容

Adobe AIR 2.5 以及更新的版本

StageWebView 類別會使用行動裝置上的系統瀏覽器控制項以及使用桌上型電腦的標準 Adobe® AIR® HTMLLoader 控制項,以顯示 HTML 內容。請核取 StageWebView.isSupported 屬性以判斷目前的裝置是否支援此類別。不保證行動描述檔中的所有裝置都支援。

在所有描述檔中,StageWebView 類別僅支援 HTML 內容與其餘應用程式之間有限的互動。您可以控制瀏覽,但是不允許資料的跨指令碼處理或直接交換資料。您可以從本機或遠端 URL 載入內容,或是傳遞 HTML 的字串。

Adobe 推薦的資源

AIR2.5 StageWebView 示範 – OAuth 支援

Mark Doherty
資訊傳播者 Mark Doherty 示範如何使用 StageWebView 類別登入像 Twitter 這種受 OAuth 保護的網站。

StageWebView 物件

StageWebView 物件並非顯示物件,因此無法新增至顯示清單。而是以直接附加至舞台的檢視區域來運作。StageWebView 內容會在任何顯示清單內容上方繪製。您無法控制多個 StageWebView 物件的繪製順序。

若要顯示 StageWebView 物件,您可以將要顯示該物件的舞台指定給 StageWebView 的 stage 屬性。使用 viewPort 屬性可設定顯示的大小。

請在 -8192 與 8191 之間設定 viewPort 屬性的 x 與 y 座標。寛度與高度的最大值為 8191。如果大小超過最大值,會擲出例外。

下列範例會建立 StageWebView 物件,並設定 stage viewPort 屬性,然後顯示 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 );

若要隱藏 StageWebView 物件,請將其 stage 屬性設定為 null 。若要刪除整個物件,請呼叫 dispose() 方法。您可以選擇性呼叫 dispose() ,但是確實能協助垃圾回收器較快回收物件使用的記憶體。

內容

您可以使用兩種方法,將內容載入 StageWebView 物件: loadURL() loadString()

loadURL() 方法會在指定的 URL 載入資源。您可以使用系統網頁瀏覽器控制項支援的任何 URI 配置,包括 data:、file:、http:、https: 和 javascript:。不支援 app: 與 app-storage: 配置。AIR 不會驗證 URL 字串。

loadString() 方法會載入包含 HTML 內容的常值字串。以此方法載入的頁面位置會以下列方式表示:
  • 桌上型電腦:about:blank

  • iOS: htmlString

  • Android:編碼過的 htmlString 資料 URI 格式

URI 配置會判斷載入內嵌內容或資料的規則。

URI 配置

載入本機資源

載入遠端資源

本機 XMLHttpRequest

遠端 XMLHttpRequest

data:

file:

http:、https:

相同網域:

about: (loadString() 方法)

備註: 如果將舞台的 displayState 屬性設定為 FULL_SCREEN ,則在桌上型電腦中,您無法在 StageWebView 中顯示的文字欄位內進行輸入。不過,在 iOS 與 Android 中,即使舞台的 displayState FULL_SCREEN ,您仍然可以在 StageWebView 的文字欄位中輸入。

下列範例使用 StageWebView 物件來顯示 Adobe 的網站:

package  { 
    import flash.display.MovieClip; 
    import flash.media.StageWebView; 
    import flash.geom.Rectangle; 
     
    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" ); 
        } 
    } 
}

在 Android 裝置上,您必須指定 Android INTERNET 權限,應用程式才能順利載入遠端資源。

在 Android 3.0+ 中,應用程式必須在 AIR 應用程式描述器的 Android manifestAdditions 元素中啟用硬體加速,才能顯示 StageWebView 物件中的外掛程式內容。請參閱 在 StageWebView 物件中啟用 Flash Player 和其他外掛程式

JavaScript URI

您可以使用 JavaScript URI,來呼叫 StageWebView 物件載入之 HTML 頁面所定義的函數。使用 JavaScript URI 呼叫的函數會在載入的網頁內容中執行。下列範例使用 StageWebView 物件來呼叫 JavaScript 函數:

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 ); 
        } 
    } 
}

瀏覽事件

當使用者按一下 HTML 中的連結時,StageWebView 物件會傳送 locationChanging 事件。您可以呼叫事件物件的 preventDefault() 方法,以停止瀏覽。否則,StageWebView 物件會導覽至新頁面,並傳送 locationChange 事件。當頁面載入完成時,StageWebView 會傳送 complete 事件。

每個 HTML 重新導向都會傳送 locationChanging 事件。在適當時機會傳送 locationChange complete 事件。

在 iOS 上,除了第一個 loadURL( ) 或 loadString() 方法以外,會在 locationChange 事件之前傳送 locationChanging 事件。也會透過 iFrame 與 Frame 為導覽變更傳送 locationChange 事件。

下列範例說明您如何防止位置變更,並改在系統瀏覽器中開啟新頁面。

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 ) ); 
        } 
    } 
}

步驟記錄

使用者按一下 StageWebView 物件所顯示內容的連結時,此控制項會儲存向後與往前的操作記錄堆疊。下列範例說明如何導覽兩個操作記錄堆疊。此範例使用「後退」和「搜尋」軟鍵。

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(); 
            } 
        } 
    } 
}

焦點

雖然它不是顯示物件,但是 StageWebView 類別包含的成員可讓您管理此控制項的焦點轉換。

當 StageWebView 物件獲得焦點時,它會傳送 focusIn 事件。若有必要,您可以使用此事件來管理應用程式中的焦點元素。

當 StageWebView 放棄焦點時,它會傳送 focusOut 事件。當使用者使用裝置軌跡球或方向鍵在網頁上「點擊」,以傳遞第一個或最後一個控制項時,StageWebView 實體可能會放棄焦點。事件物件的 direction 屬性可讓您知道焦點流排是否超過頁面的頂端或頁面的底端。使用此資訊以指定焦點至 StageWebView 上方或下方的適當顯示物件。

在 iOS 上,無法以程式設計方式設定焦點。StageWebView 會傳送 focusIn focusOut 事件,並將 FocusEvent 的 direction 屬性設定為 none 。如果使用者在 StageWebView 內部觸控,會傳送 focusIn 事件。如果使用者在 StageWebView 外部觸控,會傳送 focusOut 事件。

下列範例說明如何將焦點從 StageWebView 物件傳遞至 Flash 顯示物件:

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; 
        } 
         
    } 
}

點陣圖捕捉

StageWebView 物件會顯示在所有顯示清單內容的上方。您無法在 StageWebView 物件的上方新增內容。例如,您無法在 StageWebView 內容上方展開下拉式清單。若要解決這個問題,請捕捉 StageWebView 的快照。然後,隱藏 StageWebView 並改為新增點陣圖快照。

下列範例說明如何使用 drawViewPortToBitmapData 方法補捉 StageWebView 物件的快照。它透過將舞台設定為 null,以隱藏 StageWebView 物件。在完全載入網頁後,它會呼叫補捉點陣圖的函數並顯示它。當您執行時,程式碼會顯示兩個標籤:Google 與 Facebook。按一下標籤會補捉對應的網頁,並將它顯示為舞台上的快照。

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); 
        } 
    } 
}