2
votes

In my Flex mobile app, everything is fine on the AIR "adl" emulator running on my computer. But when I deploy the app to my Android phone or tablet, I run into this peculiar problem:

The app works fine when launched in landscape, but when I start it in portrait mode, it just shows a blank white screen. If I rotate it into landscape mode, it renders right away, and I can rotate it back into portrait mode and it still works.

I did some debugging, and it seems that when opened in portrait, the view never gets added to the stage, or even reaches creationComplete. But if I rotate into landscape, it does so immediately.

Any ideas?

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                            xmlns:s="library://ns.adobe.com/flex/spark"
                            firstView="views.HomeView">

<fx:Metadata>
    [ResourceBundle("resources")]
</fx:Metadata>

<!-- Global CSS styles -->
<fx:Style source="styles/AppStyles.css" />

<fx:Script>
    <![CDATA[
    // Initialize some vars...
    ]]>
</fx:Script>

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

</s:ViewNavigatorApplication>

Views/HomeView.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:components="components.*"
    creationComplete="init()" menuKeyPressed="handleMenuKeyPressed(event)"
    title="...">
<s:states>
    <s:State name="portrait" />
    <s:State name="landscape" />
</s:states>

<fx:Script source="ViewHandler.as" />
<fx:Script source="HomeViewHandler.as" />
<fx:Style  source="../styles/HomeViewStyles.css" />

.....
<s:Label id="resultsHeading" text="{s('Results')}" fontWeight="bold" addedToStage="setResultsHeadingFont()" />
    <s:HGroup width="100%" layoutDirection="{s('layoutDirection')}">
        <s:Group id="mainResultsGroup" width="90%">
            <s:layout.portrait>
                <s:VerticalLayout />
            </s:layout.portrait>
            <s:layout.landscape>
                <s:HorizontalLayout gap="{getScaledNumber(100)}" />
            </s:layout.landscape>
            <s:VGroup>
.....

Here init() never gets called until app is in landscape orientation.

-- UPDATE: Here's my application.xml:

<?xml version="1.0" encoding="utf-8"?>
<application xmlns="http://ns.adobe.com/air/application/4.0">
  <id>com.myapp</id>
  <versionNumber>0.1</versionNumber>
  <supportedProfiles>mobileDevice</supportedProfiles>
  <filename>MyApp</filename>
  <name>
    <text xml:lang="en">My App</text>
  </name>
  <android>
    <manifestAdditions><![CDATA[<manifest android:installLocation="auto">
    <uses-sdk android:minSdkVersion="8" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch" />
</manifest>]]></manifestAdditions>
  </android>
  <iPhone>
    <InfoAdditions><![CDATA[<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleBlackOpaque</string>
<key>UIRequiresPersistentWiFi</key>
<string>NO</string>
<key>UIPrerenderedIcon</key>
<true />
<key>UIApplicationExitsOnSuspend</key>
<true />
<key>UIDeviceFamily</key>
<array>
    <!-- iPhone support -->
    <string>1</string>
    <!-- iPad support -->
    <!--<string>2</string>-->
</array>]]></InfoAdditions>
    <requestedDisplayResolution>high</requestedDisplayResolution>
  </iPhone>
  <initialWindow>
    <title>My App</title>
    <content>MyApp.swf</content>
    <visible>true</visible>
    <fullScreen>false</fullScreen>
    <autoOrients>true</autoOrients>
    <!--<aspectRatio>landscape</aspectRatio>-->
    <renderMode>cpu</renderMode>
    <systemChrome>standard</systemChrome>
  </initialWindow>
  <icon>
    <image48x48>icons/icon_48.png</image48x48>
    <image57x57>icons/icon_57.png</image57x57>
    <image72x72>icons/icon_72.png</image72x72>
    <image96x96>icons/icon_96.png</image96x96>
    <image114x114>icons/icon_114.png</image114x114>
    <image144x144>icons/icon_144.png</image144x144>
    <!--<image512x512>icons/icon_512.png</image512x512>-->
  </icon>
  <description>
    <text xml:lang="en">
    </text>
  </description>
</application>

BTW I'm using FlashDevelop.

2
Could you post your [Main]-app.xml file? I'm thinking the values of <aspectRatio> or <autoOrients> may not be set appropriately.Brian
@Brian I updated it and added it.SZH
What are you using the landscape and portrait States for?Josh
Try adding preinitialize and initialize listeners on your application and view classes; debugging with those might give you more clues.Brian
@JoshJanusch I updated the question with that code. I'm using it for choosing between layout typesSZH

2 Answers

0
votes

In your [project]-app.xml file, make sure that you have the following line:

<autoOrients>true</autoOrients>

This value defaults to false, so you'll need to make sure you've set it for your app to start properly in both orientations.

0
votes

I finally got it working, and I can't explain how or why this works.

I have a custom component at the bottom of HomeView.mxml:

<components:MyCustomComp id="customComp" right="0" left="0" bottom="0"
                         height="40%" maxHeight="700" />

When I set the height property to a number instead of a percentage, everything works fine. But I want a percentage, so instead I leave out the height property in the MXML, and when I initialize the view, I set customComp.percentHeight = 40; and magically it loads perfectly.

Sometimes Flex really perplexes me...

FWIW, the custom component is the last in the View, and is removed and added again as needed from code. When in use, it overlays over the rest of the components in the View. It is a direct child of the view, not inside a Group. Maybe this will help someone else.

UPDATE:

It turns out that the above didn't completely fix it. I ended up needing to remove the maxHeight property as well. Setting maxHeight in AS3 didn't fix it either; I had to remove it completely.