Adding background image to mx component while using flex 4
Again, a theming question. Because the project I'm working on requires older libraries that extend mx components (such as TitleWindow and TabNavigator), I can't use what I know about Spark skinning directly. However, since the project is being programmed using the default Spark theme (with my modifications on top) rather than the Halo theme, I apparently don't have access to the styles I need (namel开发者_运维技巧y backgroundImage and contentBackgroundImage which apparently require Halo to be active). Simply setting Halo to be the theme will break other things, not the least of which my own theme. Plans are in the works to replace the older libraries or at least patch them better to Flex 4, but as of right now, I need a way to style/skin these components without modifying them directly.
It would be ridiculous to be unable to add a background image to a TitleWindow's content area! I've searched the internet high and low all day and tried countless variations of styles, skins, selectors, and combinations thereof with no luck. Doesn't anyone know how to add a background image to the content of a mx TitleWindow while using the Flex 4.1 sdk?!
Actually, it's not the only way, it's -as you've mentioned- the hardcoded way: sorry about that. You can also skin your TitleWindow component to accept background images.
To create the appropriate skin with all the necessary states, you can copy the base skin: spark.skins.spark.TitleWindowSkin
as MyTitleWindowSkin
, and add some customization to it:
In the MetaData tag you should enter the name of your custom TitleWindow class:
<fx:Metadata>
<![CDATA[
[HostComponent("my.package.CustomTitleWindow")]
]]>
</fx:Metadata>
To accept backgroundImage,
- you should declare a variable: [Bindable] private var backgroundImage:*;
- override the
updateDisplayList(unscaledWidth, unscaledHeight)
method, and inside of it initialize this member:backgroundImage = getStyle("backgroundImage");
in the
<!-- layer 2: background fill -->
section, after the solid-color-fill (<s:Rect id="background"...
), you should put the following snippet:<s:Rect id="backgroundImg" left="1" right="1" top="{topGroup ? topGroup.height : 0}" bottom="{bottomGroup ? bottomGroup.height : 0}"> <s:fill> <!-- BackgroundImage --> <s:BitmapFill id="img" source="{backgroundImage}" smooth="true" fillMode="scale" /> </s:fill> </s:Rect>
Next you need to create a new class (my.package.CustomTitleWindow
), that extends TitleWindow, set its skin, and bind the backgroundImage style:
<?xml version="1.0" encoding="utf-8"?>
<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
skinClass="my.package.MyTitleWindowSkin">
<fx:Metadata>
[Style(name="backgroundImage", type="*")]
</fx:Metadata>
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
at the end a small test (which worked fine at my side, and i hope it's closer to what you're looking for):
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<my:CustomTitleWindow title="Window without background image"
width="100%" height="50%" />
<my:CustomTitleWindow title="Window with background image"
width="100%" height="50%" backgroundImage="{IMyConstants.MYLOGO}" />
</s:VGroup>
Update
For setting the skin and the background image from a css file, you only need some minor modifications:
Create a CSS file with content:
/* CSS file */
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace my "your.package.*";
my|CustomTitleWindow {
skin-class: ClassReference("your.package.MyTitleWindowSkin");
}
.twWithBgImage {
background-image: Embed("icons/logo.png");
}
The test would look like:
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<my:CustomTitleWindow title="Window without background image"
width="100%" height="50%" />
<my:CustomTitleWindow title="Window with background image"
width="100%" height="50%" styleName="twWithBgImage" />
</s:VGroup>
and you need to remove the skin declaration from the CustomTitleWindow class: skinClass="your.package.MyTitleWindowSkin"
.
Of course you don't need to apply the skin to the my|CustomTitleWindow class, you could use it just for a css class, this way you surely don't need to modify your existing component.
Update -- without custom component
Forget the CustomTitleWindow class.
skinnedtw.css
/* CSS file */
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
.twWithBgImage {
skin-class: ClassReference("your.package.MyTitleWindowSkin");
background-image: Embed("icons/logo.png");
}
TestApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Style source="assets/skinnedtw.css" />
<s:VGroup width="100%" height="100%" paddingLeft="10" paddingTop="10" paddingRight="10">
<s:TitleWindow title="Window without background image"
width="100%" height="50%">
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
<s:TitleWindow title="Window with background image"
width="100%" height="50%" styleName="twWithBgImage">
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<s:Button label="Do something" />
</mx:VBox>
</s:TitleWindow>
</s:VGroup>
</s:WindowedApplication>
My output still looks like this:
if you don't have explicit members in your mx:TitleWindow, than you should consider using
a spark BorderContainer as its first child, since you can specify a background image to that.
i'm thinking of something like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="absolute"
width="400" height="300" backgroundAttachment="">
<s:BorderContainer backgroundImage="{IMyConstants.MYLOGO}"
width="100%" height="100%" backgroundAlpha=".5" />
<mx:VBox width="100%" height="100%">
<mx:Text text="{IMyConstants.LOREMIPSUM}" width="100%" height="100%" />
<mx:Button label="Do something" />
</mx:VBox>
</mx:TitleWindow>
i hope i understood your problem, and this helps.
精彩评论