Accessibility

Table of Contents

Developing Flash Lite applications with dynamic layouts

Setting up a dynamic layout

The first step in setting up your dynamic layout is to retrieve and store some of the device properties. If you haven't already, download and examine the sample files provided on the first page of this article. The Layout class is used to determine Stage size, orientation and whether it is currently day or night. It is critical to set the application to align to the top left, and enable the full screen mode.

Here is an example of the code used to create the functionality described above:

fscommand2("FullScreen", true);

Stage.align = "TL";
Stage.scaleMode = "noScale"

var stateDay:Boolean = Layout.day;
var statePortrait:Boolean = Layout.portrait;
var stateWidth:Number = Layout.width;
var stateHeight:Number = Layout.height; 

You will also need to store the soft key location. On most devices, this value will remain static. However, you should be aware that when working with devices with resolution switching capabilities, the soft key location can change.

To detect the soft key location, use the following script:

var softKeyLocation:Number =
fscommand2("GetSoftKeyLocation");

The possible responses of the command are listed below:

-1: Not supported 
0: Soft keys on top 
1: Soft keys on left 
2: Soft keys on bottom 
3: Soft keys on right

In the FLA file included with the sample files, the variable defaults to "2" if the "GetSoftKeyLocation" command is not supported on the device. This will cause the soft key positioning function to align the soft keys to the bottom of the screen.

Switching between day and night themes

Day and night themes are automatically activated by the device's current time. This is accomplished by monitoring the "day" property of the Layout class on an interval.

Here's the function that monitors the day property:

import pixologist.mobile.Layout;
 
function timeChange(){
     if(stateDay != Layout.day){
          stateDay = Layout.day;
          buildBg();
     }
}


dayMonitor = setInterval(timeChange, 1000);
timeChange();

When the function determines that the day property of the Layout class is no longer equal to the stateDay variable that we defined at startup, it updates the variable and calls buildBg(), the function responsible for adjusting the theme. The buildBg function removes the current background image if one exists, and replaces it with the appropriate one. Backgrounds are stored in the library as movie clips with the following linkage identifiers:

darkLandscape
darkPortrait
lightLandscape
lightPortrait

The buildBg function creates the linkage id by concatenating two strings based on current device conditions.

Here's the buildBg function:

function buildBg():Void{
     var imageId:String;
     stateDay ? imageId = "light" : imageId = "dark"; 
     statePortrait ? imageId += "Portrait" : imageId += "Landscape";

         if(typeof(bg.oldBg) == "movieclip"){bg.oldBg.removeMovieClip();}

     var bgImage:MovieClip = bg.attachMovie(imageId, imageId, bg.getNextHighestDepth()); 
     bg.oldBg = bgImage;
     positionSoftKeys();
}

The variables we defined earlier are coming into play. The values must be updated before calling the buildBg function in order to make the theme change. The Layout class includes two variables for assigning when daytime has started and ended. They are beginDay and endDay. The default value for the beginning of a day is 5, and the end is 18. To cause an immediate change you would toggle the invertDay Boolean property of the Layout class. This causes the application to use the night theme for day time. To return to the standard day or night themes, you must reset the invertDay property to false.

Demo: To see this functionality in action, run the application provided in the sample files and press the soft key labeled "TIME."

Here is an example of how to switch themes on demand:

import pixologist.mobile.Layout;
Layout.invertDay = !Layout.invertDay;
timeChange();

To prevent automatic switching based on device time, you can deactivate the dayMonitor interval or simply remove it entirely.

Here is an example of how to do that:

clearInterval(dayMonitor);

Switching between portrait and landscape themes

Orientation change is achieved two different ways. In the first method, the device's resolution never actually changes; the movie clip in which the application resides is rotated and repositioned to one of four possible positions. Four objects are created to store the various properties required to fully rotate the application.

Here are the rotation objects and the function that governs them:

var rotations:Object = new Object();
rotations.index = 0;

function setRotationModes(){

    var softKeyLocation:Number = fscommand2("GetSoftKeyLocation");
    if(softKeyLocation == -1) softKeyLocation = 2;
         var softKeyLocations:Array = [];
         var number:Number = softKeyLocation;
         for(var i:Number = 0; i<=3; i++){
              softKeyLocations.push(number);
              number ++;
              if(number > 3) number = 0;
              }
         var rotationA:Object = {_id:softKeyLocations[0], _name:"origin",_x:0, _y:0, _rotation:0, _portrait:statePortraitDefault}
         var rotationB:Object = {_id:softKeyLocations[1], _name:"right", _x:Layout.width, _y:0, _rotation:90, _portrait:!statePortraitDefault}
         var rotationC:Object = {_id:softKeyLocations[2], _name:"top", _x:Layout.width, _y:Layout.height, _rotation:-180, _portrait:statePortraitDefault}
         var rotationD:Object = {_id:softKeyLocations[3], _name:"left", _x:0, _y:Layout.height, _rotation:-90, _portrait:!statePortraitDefault}
         rotations.list = [rotationA,rotationB,rotationC,rotationD];
 }

All of the rotation objects are stored within the rotations object. The rotation objects also govern how the soft keys will be repositioned upon orientation change. It is critical that the soft keys are always correctly positioned according to their physical location on the device so that users are not confused by the change.

You can rotate the app to any of the rotation modes on demand by using the orientationRotation function. By passing a number (0 through 3) you can specify which of the modes to go to directly. If you do not specify a value, the function will cycle through each of the available modes. Calling the function again with the toggle parameter set to true will cause the application to toggle between the specified rotation and the default rotation detected at start up, or after the last Stage resize.

Demo: To see this functionality in action, run the application and use the 5 way navigation. Press the directional keys to align the Stage to that direction and press enter to cycle through all of the directions.

Here's the orientationRotation function:

function orientationRotation(rotation:Number, toggle:Boolean){
     var currentRotation:Object = rotations.list[rotations.index]; 
     if(rotation != undefined){
          if(toggle){
               rotations.index != 0 ? rotations.index = 0 : rotations.index = rotation; }
          else{
              rotations.index = rotation;
          }
     }
     else{ 
     rotations.index < rotations.list.length-1 ? rotations.index ++ : rotations.index = 0;
 }
     var newRotation:Object = rotations.list[rotations.index]; 
     tLevel._x  = newRotation._x;
     tLevel._y  = newRotation._y;
     tLevel._rotation = newRotation._rotation;
     if(rotation == undefined){
          Layout.invertPortrait = !Layout.invertPortrait;
     }
     else{
          if(newRotation._portrait != currentRotation._portrait){
               Layout.invertPortrait = !Layout.invertPortrait;
          }
     }
     orientationChange();
 }

A Stage resize listener is employed for devices capable of changing their screen resolution. It resets all positioning variables, detects the current orientation, and updates some of the state variables we defined earlier. After all the values have been reset, the orientationChange function is called. The two functions are used independently based on whether or not an actual resolution change has occurred or if the orientation change is actually a Stage rotation.

Here's the resize listener:

import pixologist.mobile.Layout;
 
function orientationChange(){

     statePortrait  = Layout.portrait;
     stateWidth  = Layout.width;
     stateHeight  = Layout.height; 
     buildBg();
     setRotationModes();
}
 
var listenerStageResize:Object = new Object();
listenerStageResize.onResize = function(){ 
     tLevel._x = 0;
     tLevel._y = 0;
     tLevel._rotation  = 0; 
     statePortraitDefault  = Layout.portrait;
     Layout.invertPortrait  = false;
     rotations.index = 0;
     setRotationModes();
     orientationChange();
}
Stage.addListener(listenerStageResize);

In the Bacardi® Mobile Cocktail application, a resize event is dispatched to the current section of the application. The current section then adjusts itself to the current size and orientation. In the examples below, you can see that the amount of visible drinks increases from 5 to 7 in landscape mode (see Figures 3 and 4).

The cocktail section of the application displayed in the night /
  landscape mode

Figure 3. The cocktail section of the application displayed in the night / landscape mode

Figure 4. The cocktail section of the application displayed in the night / portrait mode