2
votes

I knew I can set custom skin for a spark components. Is it possible to set attribute of skinClass in actionscript? Here is the example:

  1. a customized button like:

    < view:SparkButton height="24" icon="@Embed('left.gif')" />

  2. its skinClass snippet:

    < s:Rect id="border" left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2">

    <s:stroke>
        <s:LinearGradientStroke rotation="90" weight="1">
            <s:GradientEntry color="0xFFFFFF" alpha="0.5625" alpha.down="0.6375" />
            <s:GradientEntry color="0xFFFFFF" alpha="0.75" alpha.down="0.85" />
        </s:LinearGradientStroke>
    </s:stroke>
    

    < /s:Rect>

  3. in a as file where the customized SparkButton is used, is it possible to dynamically set or modify the attribute (like s:Rect visible or the color of one of s:GradientEntry ) of border? like "SparkButton.border....visible = false"? Or what I can do is to modify the skinClass in its mxml file?

1

1 Answers

1
votes

Technically the answer is: yes, you can access the skin's properties. The SkinnableComponent class has a public skin property which contains a reference to the skin instance applied to that component. So in order to set a property of that skin instance directly, you could do something like this:

var skin:MyButtonSkin = myButton.skin as MyButtonSkin;
skin.myProperty = "someValue";

Note that you'll have to cast if you want access to custom properties that are not already present on UIComponent.


However this is not a good approach, because it creates dependencies we can avoid. If some day we want to use another skin on that custom Button, this code will break.

There are quite a few ways to handle this more elegantly, but since your question is rather broad (I don't have a concrete example to work with) I'll just give you an overview of some possibilities:

1. Use the skin's states to update its properties

For instance: <s:Rect id="border" visible.down="false" ...>. Since you're working with a Button here, there are already some states predefined, but you can add your own by overriding getCurrentSkinState() in your custom Button class.

2. Use styles instead of properties

You can create custom styles as you like.

view|SparkButton {
    backgroundVisible: false;
}

view|SparkButton.withBackground {
    backgroundVisible: true;
}

and use it in the skin:

<s:Rect id="border" visible="{getStyle('backgroundVisible')}" ...>

3. Wrap the properties on the host component.

The "host component" in this case is your custom button class. Create a property on it, e.g.

[Bindable]
public var backgroundVisible:Boolean;

You can now access this property on the skin like so:

<s:Rect id="border" visible="{hostComponent.backgroundVisible}" ...>

Because we made the property bindable, the skin will update whenever you set the property on the Button itself.

Note that this last approach is probably the easiest, but it comes at a price: it creates a dependency between the component and its skin. This is not much of an issue if you always intend to use that specific skin with that specific component. But if you need more flexibility, better go for one of the two other options.