While developing a new Flex 4.5 application I needed to add a background to all the views. I was using ViewNavigatorApplication, pushing and popping views as the user navigated through the app, with slide effect in between. This made it impossible to add the background to every view, because you would see it slide as well.
The best way to solve it was to create a custom application skin. I inherited the ViewNavigatorApplicationSkin class and simply overrided the createChildren method to add the background. In my case, it was an image, but you can just as easily have shapes, primitives or components.
Here's the code:
package skins { import mx.core.BitmapAsset; import spark.components.Image; import spark.skins.mobile.ViewNavigatorApplicationSkin; public class AppSkin extends ViewNavigatorApplicationSkin { private var image:Image; [Embed(source="bkd.jpg")] private var background:Class; public function AppSkin() { super(); } override protected function createChildren():void { image = new Image(); //Replace the right side below with your source (including URL) image.source = (new background() as BitmapAsset); image.height = 600; //Set image size here image.width = 1024; this.addChild(image); super.createChildren(); } } }
1. | package skins |
2. | { |
3. | import mx.core.BitmapAsset; |
4. | import spark.components.Image; |
5. | import spark.skins.mobile.ViewNavigatorApplicationSkin; |
6. | |
7. | public class AppSkin extends ViewNavigatorApplicationSkin |
8. | { |
9. | private var image:Image; |
10. | |
11. | [Embed(source="bkd.jpg")] |
12. | private var background:Class; |
13. | |
14. | public function AppSkin() |
15. | { |
16. | super(); |
17. | } |
18. | |
19. | override protected function createChildren():void { |
20. | image = new Image(); |
21. | //Replace the right side below with your source (including URL) |
22. | image.source = (new background() as BitmapAsset); |
23. | image.height = 600; //Set image size here |
24. | image.width = 1024; |
25. | this.addChild(image); |
26. | |
27. | super.createChildren(); |
28. | } |
29. | } |
30. | } |
Then, in the application, you just have to set the skinClass style property to skins.AppSkin and make sure that any view component that has a background disables it (such components are View and List) so we can set their backgroundAlpha to 0 through CSS, ensuring that all instances are covered. See below:
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" skinClass="skins.AppSkin" xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.testMobileHomeView"> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; s|View { backgroundAlpha: 0; } s|List { backgroundAlpha: 0; } </fx:Style> </s:ViewNavigatorApplication>
1. | <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" skinClass="skins.AppSkin" |
2. | xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.testMobileHomeView"> |
3. | <fx:Style> |
4. | @namespace s "library://ns.adobe.com/flex/spark"; |
5. | |
6. | s|View { |
7. | backgroundAlpha : 0; |
8. | } |
9. | |
10. | s|List { |
11. | backgroundAlpha : 0; |
12. | } |
13. | </fx:Style> |
14. | </s:ViewNavigatorApplication> |
15. |
Similarly, you can do the same for a TabbedViewNavigatorApplication by inheriting the TabbedViewNavigatorApplicationSkin
Subscribe to:
Post Comments (Atom)
19 comments:
Can you look into this? Should this still work. I've been trying a million different ways to get a bg image in my mobile tabbed app in 4.5.1. Nothing works, including this approach.
Thanks
@bmanderscheid Sorry, there was a mistake in my original post. I updated it now, check out the IMPORTANT part, and make sure you add that to your project. Let me know if it this fixed it for you.
Thanks as this solution worked for me. But this worked for me only in views where am using smaller controls like buttons etc which do not occupy fullscreen.
I have a view with a List in it and this list occupies the entire screen. In this case the list as well as my inline item renderer has no background alpha property. So how can I make the background image work in this view as well. Your help is highly appreciated. Many thanks,
@aXis That's happening because the list has its own background. To remove that you can use the contentBackgroundAlpha, setting it to 0 in the CSS file like this:
s|List {
contentBackgroundAlpha: 0;
}
If you have a custom item renderer, it might be that this has background as well. You can read more about Spark list customizing here : http://spy6.blogspot.com/2010/09/spark-custom-item-renderers.html
import models.Icons;
...is not resolving in Flash Builder 4.5.1
Also, I am not clear on where the background asset is being loaded from.
Thanks for any extra info. Your post has helped.
@Dark Code
The Icons class is basically a place where I stored all the embedded assets. I have redone the example to make it a bit simpler to understand and I embedded the image directly in the class.
You can also load the background asset dynamically by setting a URL for the source.
trying to get this to work, doesnt show the image, just another grey banner across the top under the ActionBar..? I guess Im doing something wrong.
I have an image called bkd.jpg in the skins folder.
I have created AppSkin.as in the asset folder, and copied that code as is.
I have added skinClass=skins.AppSkin to the main view.
... but still doesnt show the bkd.jpg image, just another grey bar at the top! Any ideas please?
Has anyone got this to work in FlashBuilder?
thanks!
i have created a simple skin class and added skinClass="appcode.BgViewSkin" in default view, but after compiling it doesn't show the image.
If you not set the backgroundAlpha="0" in your View, the background will not show with this trick.
Tried hard to add a background image as described, but without any luck. I followed your code and created a custom skinclass added a reference to the application with skinClass property. But nothing is showing... What is wrong ?
haven't had any luck with the image actually showing up.. set the background of my views to black and just one of them to backgroundAlpha=0.. the one with background alpha is definitely see through but the image isn't displaying. Also confirmed that it is calling the script, but still no luck
Guys, I have updated the post with the backgroundAlpha trick, please take another look and make sure you are doing everything as per the example.
If it still does not work try uploading your sample somewhere and post a link here. I can take a look and see if I missed something in my example.
But again, it should work perfectly in Flash Builder, I started it from scratch today and I got the background.
discovered my issue.. in your source it says that you can use percentWidth and percentHeight.. that was causing the image to not display.. guessing that the width and height aren't know that early
@Marc Pelland Thanks for the update, I removed that comment.
Hi @Spy 6, your example is fantastic, but I cannot find here or in other websites how to repeat a background image (like CSS background-repeat property) or set multiple size images for different mobile screens.
Thanks in advance.
The example is purely awesome, but I can't make the image to either repeat or fit exactly in the middle of the screen
I tried with:
image.fillMode = BitmapFillMode.REPEAT;
but I can't make it work. Any help would be greatly appreciated. Thanks.
To resize image to the actual view size add this code to skin class:
override protected function drawBackground(w:Number, h:Number):void
{ super.drawBackground(w,h);
image.height=h; image.width=w;
}
how do you change the background image based on orientation change?
@Adrian, did this yesterday.
Something like
override protected function drawBackground(w:Number, h:Number):void{
super.drawBackground(w,h);
group.height=h;
group.width=w;
}
override protected function createChildren():void {
var rec:Rect = new Rect();
var bitmapFill:BitmapFill = new BitmapFill();
rec.percentHeight=100;
rec.percentWidth=100;
bitmapFill.source =(new background() as BitmapAsset);
bitmapFill.fillMode = BitmapFillMode.REPEAT;
rec.fill = bitmapFill;
group.addElement(rec);
this.addChild(group);
super.createChildren();
}
Post a Comment