Andy Hulstkamp

about creating online experiences

09. July 2009

Custom PopUp Rating Component in Spark Flex 4

I was experimenting a little with the PopUpAnchor in Spark Flex 4 and came up with a new custom component for ratings.

City Rating Component

The new component has the following characteristics:

  • Show a placeholder-icon that reflects the current rating and serves as an interactive element to open the ratings
  • ratings pop up for adjustment
  • both the placeholder-icon and the ratings-icons will be gradually filled with color when adjustments are being made
  • the icons are defined in FXG
  • the icons are not defined in the skin but can be passed as a style for generic use (one skin for different icons and ratings)
  • there is colorization of the icons based on styles
  • smooth transitions when opening the ratings

Here’s a pseudo city-rating demo that shows variations of the component using different icons and color settings for different ratings.

You’ll find the source at the end of this post. It is fully documented but here’s an overview of the key-concept nonetheless.

Skin-Parts

There are skin-parts for the open-button (which is actually a group that works as a button), the drop-down which is a group that holds the entire pop-up, the active-group and the passive-group that hold the icons for adjustments of the rating and the label-element to show the rating as text.

Building the View

The icons are not part of the skin. They will be set at run time and are pushed down to the skin when the component loads the different skin-parts.

In partAdded() of the component, the active-group and the passive-group are filled with the icons. Five icons in a colorized version are pushed down to the active part. Five default icons are pushed down to the passive-group.

Masking and Fill Effect

To create an effect that gives the impression of gradually filling the icons when the rating is adjusted, masks are used. When skin-parts are loaded, the component applies a mask to the active-group. When the mouse is dragged to adjust the rating, the width of the mask is updated and the (colorized) icons of the active-group are revealed.

The mask is not part of the skin. It is created at run-time by the component and applied to the relevant skin-part. FXG Icons passed via Styles

The Icons are defined in FXG. Basically each Icon is a MXML-Component. The Icons are passed as a ClassReference to the component via styles. The ClassReference is then used to create an instance of this class at run-time. The instances of the icon are then added to their respective groups. An Icon is basically a mxml-component that extends from Group. You can create your own and reference it via the rating Icon style.

Colorization based on Styles

The Icons are colorized at run-time. Based on some colors that are passed as styles the icons get colorized using a ColorTransform.

Effects on PopUp

There is a resize and a fade effect when the pop up is openend. These are defined on the skin - you can remove them by simply commenting out the transition part in the skin.

Separation of Concerns

Spark promotes a clean separation of concerns. The Component should keep track of the data/state and work as a controller, the skin is there for the view. I decided to create and update the mask in the component, because the masking effect is an inherent part of this implementation and setting up the masking infrastructure in the component helps to keep the skin cleaner. Another approach would be to define the mask in the skin, then pull the value for the rating from the component and adjust the mask accordingly. Still, every aspect of the look (gap, background-colors, borders, effects etc.) is controlled by the skin.

How to use

Setting the basic styles for the AHPopUpRatingComponent:

ah|AHPopUpRatingComponent {
    skinClass: ClassReference('AHPopUpRatingComponentSkin');
    passiveIconColor: "0x808080";
    activeIconColor: "0xc0c0c0";
    baseColor: "0xb0b0b0";
}

Using a variation of style values: For this example use styleName=’medicareRating’ on the component to set the css-class. It uses the Icon under myLibrary.HealthCross and has a light blue color for the active icons.

ah|AHPopUpRatingComponent.medicareRating {
    ratingIcon: ClassReference('myLibrary.HealthCross');
    activeIconColor: "0xCAEAFF";
}

The icons are mxml-components, that extend from Group. Use the fully qualified class-path in the ClassReference of the ratingIcon-style to reference the icon. Here’s an example:

<s:Group horizontalCenter="0" verticalCenter="0" width="25" height="25"  xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
    <s:Path  x="5" winding="nonZero" ai:knockout="0" data="M 9.404 0.01 C 9.051 8.355 -1.506 9.232 3.065 16.324 C 1.835 17.4 0.006 19.866 0.006 25.01 L 1.886 25.01 C 1.886 20.554 3.357 18.569 4.244 17.776 C 18.309 18.361 13.558 4.163 9.404 0.01 Z" >
        <s:fill>
            <s:LinearGradient x="6.82861" y="0.00683594" scaleX="25" rotation="90">
                <s:GradientEntry color="0xfbfbfb" ratio="0"/>
                <s:GradientEntry color="0xdcdcdc" ratio="0.5"/>
                <s:GradientEntry color="0xcccccc" ratio="0.5"/>
                <s:GradientEntry color="0x909090" ratio="1"/>
            </s:LinearGradient>
        </s:fill>
        <s:stroke>
            <s:SolidColorStroke color="0xd8d8d8" caps="none" weight="1" joints="miter" miterLimit="4"/>
        </s:stroke>
    </s:Path>
</s:Group>

further reading

Getting Vector Graphics into Spark Skins

How to get vector graphics into flex Skins

Custom Spark CheckBox Component in Flex 4 (Gumbo)

Post abput how to customize the Flex Spark Checkbox.