모바일 응용 프로그램에서 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 클래스를 사용하여 트위터와 같은 OAuth 보호 사이트에 로그인하는 방법을 보여 줍니다.

StageWebView 객체

StageWebView 객체는 표시 객체가 아니며 표시 목록에 추가될 수 없습니다. 대신 이 객체는 스테이지에 직접 연결된 뷰포트로 작동합니다. StageWebView 내용은 표시 목록 내용 위에 그려지며, 여러 개의 StageWebView 객체가 그려질 때 그 순서를 제어할 수는 없습니다.

StageWebView 객체를 표시하려면 객체가 나타나는 스테이지를 StageWebView의 stage 속성에 할당해야 합니다. viewPort 속성을 사용하면 표시 크기를 설정할 수 있습니다.

viewPort 속성의 x 및 y 좌표의 범위는 -8192~8191이며, 스테이지의 폭 및 높이의 최대 값은 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() 를 호출하는 것은 선택 사항이지만 이 메서드를 호출하면 가비지 수집기가 객체에 사용된 메모리를 더 빠르게 회수할 수 있습니다.

내용

loadURL() loadString() 메서드를 사용하면 내용을 StageWebView 객체 안으로 로드할 수 있습니다.

loadURL() 메서드는 지정된 URL에 있는 리소스를 로드합니다. data:, file:, http:, https:, javascript: 등 시스템 웹 브라우저 컨트롤에서 지원하는 모든 URI 스킴을 사용할 수 있으며, app: 및 app-storage: 스킴은 지원되지 않습니다. AIR는 URL 문자열의 유효성을 검사하지 않습니다.

loadString() 메서드는 HTML 내용이 포함된 리터럴 문자열을 로드합니다. 이 메서드로 로드된 페이지의 위치는 다음과 같이 표현됩니다.
  • 데스크톱의 경우: about:blank

  • iOS의 경우: htmlString

  • Android의 경우: 인코딩된 htmlString 의 데이터 URI 포맷

URI 스킴은 포함된 내용 또는 데이터를 로드하기 위한 규칙을 결정합니다.

URI 스킴

로컬 리소스 로드

원격 리소스 로드

로컬 XMLHttpRequest

원격 XMLHttpRequest

data:

아니요

아니요

아니요

file:

http:, https:

아니요

아니요

동일한 도메인의 경우

about: (loadString() method)

아니요

아니요

아니요

참고: 스테이지의 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 이상의 경우 StageWebView 객체의 플러그인 내용을 표시하려면 응용 프로그램이 AIR 응용 프로그램 설명자의 Android manifestAdditions 요소에서 하드웨어 가속화를 활성화해야 합니다. Flash Player 및 StageWebView 객체의 다른 플러그인 활성화 를 참조하십시오.

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 이벤트를 전달합니다.

locationChanging 이벤트는 모든 HTML 리디렉션에서 전달되며, locationChange complete 이벤트는 적절한 시기에 전달됩니다.

iOS에서 locationChanging 이벤트는 첫 번째 loadURL( ) 또는 l oadString() 메서드를 제외하고 locationChange 이벤트에 앞서 전달됩니다. 또한 locationChange 이벤트는 iFrames 및 Frames에서 탐색 변경이 발생하는 경우에도 전달됩니다.

다음 예제에서는 위치 변경을 방지하고 대신 시스템 브라우저에서 새 페이지를 여는 방법을 보여 줍니다.

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는 FocusEvent 의 direction 속성이 none 으로 설정된 상태에서 focusIn focusOut 이벤트를 전달합니다. 사용자가 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); 
        } 
    } 
}