Twitter: raymondcamden


Address: Lafayette, LA, USA

Using a background with a Flex Mobile project

08-24-2011 17,430 views Mobile, Flex 15 Comments

Earlier this week I started work on a new NookColor app (already done and submitted). One of the minor design elements I wanted was a simple background using a graphic. I had assumed this would be a simple matter. It's already easy to set a background color. However this turned out to be slightly more complex than I imagined. What follows is an example of how it can be done. Credit for this goes to Jason San Jose and Holly Schinsky. Please note that part of this blog entry is my understanding of what's going on and there is a strong possibility I could be wrong. Any mistakes - blame me. If it's perfect - thank them. ;)

Let's start off with a super simple Flex Mobile application. I've got a view based application with one view. Here's the top level Application.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
3                            xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.BGTestHomeView">

4    <fx:Declarations>
5        <!-- Place non-visual elements (e.g., services, value objects) here -->
6    </fx:Declarations>
7</s:ViewNavigatorApplication>

And here is my view:

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
3        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">

4    <fx:Declarations>
5        <!-- Place non-visual elements (e.g., services, value objects) here -->
6    </fx:Declarations>
7    
8    <s:VGroup horizontalAlign="center" paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10" width="100%" height="100%" verticalAlign="middle">
9        <s:Label text="Mobile Apps Rule!" width="75%" fontSize="50" textAlign="center" />        
10    </s:VGroup>
11    
12</s:View>

Which produces the lovely...

Now - if I want to add a background color, I can do so in two places - either the root app (ViewNavigatorApplication) or the view. Putting it in the root will only work for a brief second. You can see the background color for a second right before the view loads. So let's just put it in the view.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
3        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView" backgroundColor="blue">

4    <fx:Declarations>
5        <!-- Place non-visual elements (e.g., services, value objects) here -->
6    </fx:Declarations>
7    
8    <s:VGroup horizontalAlign="center" paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10" width="100%" height="100%" verticalAlign="middle">
9        <s:Label text="Mobile Apps Rule!" width="75%" fontSize="50" color="white" textAlign="center" />        
10    </s:VGroup>
11    
12</s:View>

Note the addition of "blue" to the View as well as the white color for the label. This creates this awesomely pretty view:

Ok. So when I first discovered this, I assumed that there was probably some other argument, like backgroundImage or some such, that would just as easy. Unfortunately that's not the case. Some Googling turned up a few blog posts talking about how to do it for Flex 4 apps in general. The recommendation was to create a skin for the application as a whole. You can do this in pure ActionScript or MXML. Here's my attempt with MXML.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
3                            xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.BGTestHomeView" skinClass="skins.myAppSkin">

4    <fx:Declarations>
5        <!-- Place non-visual elements (e.g., services, value objects) here -->
6    </fx:Declarations>
7</s:ViewNavigatorApplication>

Note the change here - I've added skinClass. Let's look at that file.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<s:Skin name="CustomApplicationSkin"
3        xmlns:fx="http://ns.adobe.com/mxml/2009"
4        xmlns:s="library://ns.adobe.com/flex/spark"
5         >

6
7    <fx:Metadata>
8        <![CDATA[
9        [HostComponent("BGTest")]
10        ]]>

11    </fx:Metadata>
12    
13    <s:states>
14        <s:State name="normal" />
15        <s:State name="disabled" />
16    </s:states>
17    
18    <s:BitmapImage width="100%" height="100%" source="@Embed('/images/grass.jpg')"/>
19    
20    <s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />
21    
22    <s:ViewNavigator id="navigator" width="100%" height="100%" />
23
24</s:Skin>

At first I kind of thought of the skin file like a CSS sheet, where I'd specify just what I wanted to change. But - it's more like a "skeleton" or outline for your entire application. Notice I included the viewNavigator in there. And my content group. This is - from what I understand - the default way the mobile application would be laid out anyway. So my modification then was to simply include the image. End of story, right? Not exactly.

Turns out this "works", but the View ends up covering the background picture. This is where Jason's tip came in. If we go into our view and set the alpha of the background like so:

view plain print about
1<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
2        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView" backgroundAlpha="0">

We allow the content to show the background behind it. Here's the complete view. I added a black background to the label as well.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
3        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView" backgroundAlpha="0">

4    <fx:Declarations>
5        <!-- Place non-visual elements (e.g., services, value objects) here -->
6    </fx:Declarations>
7    
8    <s:VGroup horizontalAlign="center" paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10" width="100%" height="100%" verticalAlign="middle">
9        <s:Label text="Mobile Apps Rule!" width="75%" fontSize="50" color="white" textAlign="center" backgroundColor="black" />        
10    </s:VGroup>
11    
12</s:View>

And the result:

Awesome. I bet you didn't know I was such a good designer, did you? As I said, this solution may not be 100% accurate across all situations, and there may be other ways of doing this, but I hope this is helpful to others.

15 Comments

These comments will soon be imported into Disqus. To add a comment, use Disqus above.
  • Joe #
    Commented on 08-24-2011 at 4:35 PM
    This should be added to the Tour de Flex Mobile.

    Contact them
  • Commented on 08-24-2011 at 4:46 PM
    That's Holly's app - linked to above. :)
  • Commented on 09-21-2011 at 6:57 AM
    Nice post, but this didnt work for me in Flash Builder 4.5 until I removed the height=100% from the ViewNavigator in the skinClass.

    Works now, EXCEPT the content has a background colour showing (white by default) and thus obscuring the background image! Setting the backgroundAlpha to 0 on the View, no difference.

    Any idea if there is a way round this?

    thanks
    Andy
  • Commented on 09-21-2011 at 7:56 AM
    Are you using 4.5.1? Maybe it was fixed there?
  • Commented on 09-21-2011 at 9:55 AM
    thanks Ray, good call, Im downloading the update now.
    :-)
  • Commented on 09-21-2011 at 11:25 AM
    Hey Ray,
    For what its worth, I am having a problem with the HostComponent bit. They dont make that clear what it should be set to. I had it as [HostComponent ("spark.components.TabbedViewNavigatorApplication")] because my app is a tabbed one, but it wasnt working.
    Then, I created a sample app with just one View, and set the HostComponent to the name of the app... and it works. Dont know why it doesnt work with spark.components.View, but heh!

    So now I need to figure out what to set the Host Component to for customising the background of my tabbed app. It really shouldnt be this difficult just to set a background image!!

    hopefully someone out there has cracked this...

    thanks,
    Andy
  • Commented on 09-21-2011 at 8:59 PM
    Yeah I agree. Was real surprised this wasn't simpler.
  • Fher #
    Commented on 12-14-2011 at 7:55 AM
    hi, im new developing on flex and you post works perfect. But i have a problem when run it lost an Menu. I dont know what to do, if you can help me would appreciate you. Sorry for the bad use of English. This is my code for the menu:
       <s:Button bottom="10" left="10" width="15%" height="15%" click="mx.core.FlexGlobals.topLevelApplication.viewMenuOpen=true" icon="@Embed('assets/search.png')" />
       <s:viewMenuItems>
          <s:ViewMenuItem label="por lista" icon="@Embed('assets/list.jpg')" click="navigator.pushView(listabusq)"/>
          <s:ViewMenuItem label="Top down" icon="@Embed('assets/top.jpg')" click="navigator.pushView(btopdown)"/>
          <s:ViewMenuItem label="Gps" icon="@Embed('assets/gps_icon.png')" click="whereimi(event)"/>
       </s:viewMenuItems>
  • Commented on 12-14-2011 at 8:23 AM
    Sorry - I'm not really doing Flex much more. I'd suggest posting this to the Adobe Flex forums. (Or maybe someone on this thread will know.)
  • Huseyin #
    Commented on 02-24-2012 at 3:20 PM
    Thanks! It helped me a lot.
  • Rusl #
    Commented on 05-29-2012 at 4:11 PM
    This solution was dead on. Thanks.
  • Sandy #
    Commented on 02-06-2013 at 5:32 PM
    Hey Raymond, great post!
    I've been trying to write the background skin in actionscript class (it's more lightweight for mobile app) with no success :( have you tried this before?
  • Commented on 02-06-2013 at 8:34 PM
    Sorry - I haven't used Flex in almost a year.
  • Asif Nawaz #
    Commented on 05-01-2013 at 12:42 PM
    dear Fher, I am also facing the same problem. Now my menu do not appear. Did you figure it out?
  • Commented on 06-26-2013 at 7:19 AM
    Thank you! This really helped me!