Skip to main content
Laxidasical
Known Participant
January 9, 2011
Question

Change View State Based On Screen Orientation?

  • January 9, 2011
  • 3 replies
  • 8057 views

I'd like my app to change layouts based on the current screen orientation.  I believe this is done through view states.  I have three questions...


1) How do I check the current orientation?

2) Is there an event listener that will tell me when the orientation changes?

3) How do I toggle between view states?


Thank in advance!


UPDATE: I figured out the answer to question 3...


currentState = 'yourStateName';


UPDATE II: I figured out the answer to question 1 as well.  I simply used the Capabilities object to determine the screens current width & height, then compare the two.  All of this is in a function that gets called when the app launches:


public function checkOrientation():void {

     var screenWidth:Number = Capabilities.screenResolutionX;      var screenHeight:Number = Capabilities.screenResolutionY;


     if (screenWidth > screenHeight) {currentState='yourStateName1';}      else if (screenWidth < screenHeight) {currentState='yourStateName2';}

}


Now all I have to do is figure out how to call this function when there is an orientation change.  I tried the code below but get the included error:


stage.addEventListener(Event.RESIZE, checkOrientation); // ERROR: Access of undefined property stage


Why can't access the "stage" property???

This topic has been closed for replies.

3 replies

Laxidasical
Known Participant
January 13, 2011

I have it working!  I feel like it's a hack of sorts, as I'm sure there is a better way of doing it.  Until I figure it out this will do though.


Something that slowed the process was the built in emulator in Flash Builder.  My code works flawlessly on my EVO and on the Blackberry PlayBook emulator, but not so much in Flash Builder.  I also noticed that certain graphics don't position themselves correctly in the Flash Builder emulator.


Here is what I did...

<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"

          xmlns:s="library://ns.adobe.com/flex/spark" title="Home"

          addedToStage="addedToStage()" creationComplete="checkOrientation()">

     <s:states>

          <s:State name="horizontalState"/>           <s:State name="verticalState"/>      </s:states>      <fx:Script>           <![CDATA[

               // FUNCTION THAT RUNS addToStage

               // EVENT LISTENER IS SETUP HERE

                    public function addedToStage(event:Event = null):void                     {                          stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, checkOrientation);                     }

               // FUNCTION THAT SWITCHES VIEW STATES

               // CALLED FROM addToStage & creationComplete

                    private function checkOrientation(event:StageOrientationEvent = null):void                     {                          if (stage == null)                          {                               width  = Capabilities.screenResolutionX;                               height = Capabilities.screenResolutionY;                          }                          else                          {                               width = stage.stageWidth;                               height = stage.stageHeight;                          }                if (width > height) {setCurrentState('horizontalState');}                else {setCurrentState('verticalState');}                     }

          ]]>      </fx:Script>

     <s:TextInput id="field1" y="45" text="field 1"                     x.horizontalState="33" width.horizontalState="40%"                     width.verticalState="80%" horizontalCenter.verticalState="0"/>      <s:TextInput id="field2" y="45" text="field 2"                     right.horizontalState="20" width.horizontalState="40%"                     y.verticalState="131" width.verticalState="80%"                     horizontalCenter.verticalState="0"/>      <s:Button y="232" label="Check Orientation" click="checkOrientation()"                     y.horizontalState="156" horizontalCenter.horizontalState="0"                      horizontalCenter.verticalState="0"/> </s:View>

What I don't like is that the checkOrientation function initially runs before the stage is created.  This means that I can't use stage.stageWidth & stage.stageHeight to get the width/height at that particular moment.  Instead I'm using Capabilities.screenResolutionX / Capabilities.screenResolutionY, which gives you the width/height at the time the app was first opened.  Subsequent calls use the stage properties instead though.

Inspiring
January 13, 2011

In theory you can simplify it by replacing this line:

addedToStage="addedToStage()" creationComplete="checkOrientation()">

with this (so get rid of addedToStage completely):

creationComplete="waitForStage()">

and add this method:

     public function waitForStage():void
     {
         this.addEventListener(Event.ADDED_TO_STAGE,
checkOrientation);
     }
Laxidasical
Known Participant
January 13, 2011

I tried the same approach earlier, but 1 or 2 things always happen...

  1. Flash builder threw an error stating that I couldn't use "this"
  2. The event listener was not added properly

January 12, 2011

Have you tried using the NativeApplication.nativeApplication in place of Stage?

instead of "stage.addEventListener"

try using:

"NativeApplication.nativeApplication.addEventListener"

Laxidasical
Known Participant
January 12, 2011

@naknike

I've used the addToStage property to add the event listener, that part is working great.

Where I'm stuck at is getting the current window size when the app first starts.  I tried Capabilities.screenResolutionX / Capabilities.screenResolutionY.  That simple returns the dimensions of the screen in general, not the demensions at that point in time.

Any thoughts?

Inspiring
January 12, 2011

Once 'addedToStage' has been called, it should be safe for you to access stage.stageWidth and stage.stageHeight.

If you get a stage 'null' error in the addedToStage event handler then something is very, very wrong.

Although the thought occurs that if your addedToStage event handler is in a class that doesn't extend sprite, movieclip, or another display object class, then stage will always be null.

In this case you could reference the stage from the event object which is passed to the addedToStage method, i.e. event.target.stage (and hence event.target.stage.stageWidth).

Participant
January 10, 2011

I think you have to wait for added to stage:

protected function mobileapplication1_addedToStageHandler(event:Event):void { removeEventListener(Event.ADDED_TO_STAGE,mobileapplication1_addedToStageHandler);

if(stage.autoOrients) {

     stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange);

}

protected function onOrientationChange(event:StageOrientationEvent):void {

     //your code

     //dispatchEvent(new UIEvent(UIEvent.ORIENTATION,[stage.stageWidth,stage.stageHeight, event.afterOrientation]));

}


Laxidasical
Known Participant
January 10, 2011

Hello Marek,

I'm still running into the same issue.  It says "stage" is a null object!?!?!?!

January 11, 2011

Add the resize listener to stage when loading of swf is complete. For that write this piece code:

loaderInfo.addEventListener(Event.INIT, initHandler);
in initHandler function, execute below line:

stage.addEventListener(Event.RESIZE, checkOrientation); // ERROR: Access of undefined property stage