Flex 4.5迁移问题与皮肤,过滤器和鼠标结束

时间:2011-09-07 15:44:16

标签: flex filter mouseover skin

在我的flex 4项目中,我为各种按钮定义了自定义皮肤(ToggleButtons,简单按钮等)。它使用特殊的样式属性来定义按钮是否具有内部发光。我定义了名为“normal”的css样式,当鼠标悬停在按钮上时会发光:

.normal:up {
    fillColors: #FFFFFF, #F5F5F5, #E1E1E1, #C4C4C4;
    fillRatios: 0.0, 0.5, 0.87, 1.0;
    borderColors: #E4E4E4, #A5A5A5;
    borderRatios: 0.0, 1.0;
}
.normal:over {
    fillColors: #FFFFFF, #ECF9FF, #C3E8FA;
    fillRatios: 0.0, 0.5, 1.0;
    borderColors: #E4E4E4, #A5A5A5;
    borderRatios: 0.0, 1.0;
    hasInnerGlow: true;
    innerGlowColor: #88CCF4;
}

这是ButtonBase皮肤:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="21" minHeight="21" alpha.disabled="0.5">

    <fx:Metadata>
        <![CDATA[ 
            [HostComponent("spark.components.supportClasses.ButtonBase")]
        ]]>
    </fx:Metadata>

    <fx:Script fb:purpose="styling">
        <![CDATA[         
            import flashx.textLayout.formats.TextAlign;

            import mx.graphics.GradientEntry;

            import spark.filters.DropShadowFilter;
            import spark.filters.GlowFilter;
            static private const exclusions:Array = ["labelDisplay","fill"];

            override public function get colorizeExclusions():Array {return exclusions;}

            override protected function initializationComplete():void {
                useChromeColor = false;
                super.initializationComplete();
            }  

            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void {
                updateCorners();
                updateFill();
                updateBorders();
                updateShadowAndGlow();
                updateIconAndLabel();
                super.updateDisplayList(unscaledWidth, unscaledHeight);
            }

            private function updateCorners():void {
                var tlR:Number = getStyle("topLeftRadius");
                var blR:Number = getStyle("bottomLeftRadius");
                var trR:Number = getStyle("topRightRadius");
                var brR:Number = getStyle("bottomRightRadius");

                fill.topLeftRadiusX = tlR;
                fill.bottomLeftRadiusX = blR;
                fill.topRightRadiusX = trR;
                fill.bottomRightRadiusX = brR;

                border.topLeftRadiusX = tlR+1;
                border.bottomLeftRadiusX = blR+1;
                border.topRightRadiusX = trR+1;
                border.bottomRightRadiusX = brR+1;
            }

            private function updateShadowAndGlow():void {
                var hasShadow:Boolean = getStyle("hasShadow");
                var shadowColor:uint = getStyle("shadowColor");
                var hasInnerGlow:Boolean = getStyle("hasInnerGlow");
                var innerGlowColor:uint = getStyle("innerGlowColor");
                var hasLabelShadow:Boolean = getStyle("hasLabelShadow");
                var labelShadowColor:uint = getStyle("labelShadowColor");
                var filters:Array = new Array();
                var fillFilters:Array = new Array();
                var labelFilters:Array = new Array();
                if (hasShadow){
                    filters.push(new DropShadowFilter(2.0,90,shadowColor,1.0,1.0,4.0));
                }
                if (hasInnerGlow){
                    fillFilters.push(new GlowFilter(innerGlowColor,1.0,1.0,4.0,1,1,true));
                }
                if (hasLabelShadow) {
                    labelFilters.push(new DropShadowFilter(2.0,-90,labelShadowColor,1.0,1.0,2.0));
                }
                this.filters = filters;
                fill.filters = fillFilters;
                labelDisplay.filters = labelFilters;
            }

            private function updateFill():void {
                var colors:Array = hostComponent.getStyle("fillColors");
                var ratios:Array = hostComponent.getStyle("fillRatios");
                if (colors && ratios && colors.length == ratios.length){
                    var entries:Array = new Array();
                    var entry:GradientEntry;
                    for (var i:uint = 0; i < colors.length; i++){
                        entry = new GradientEntry(colors[i],ratios[i]);
                        entries.push(entry);
                    }
                    fillGradient.entries = entries;
                }
            }

            private function updateBorders():void {
                var borderColors:Array = hostComponent.getStyle("borderColors");
                var borderRatios:Array = hostComponent.getStyle("borderRatios");
                if (borderColors && borderRatios && borderColors.length == borderRatios.length){
                    var entries:Array = new Array();
                    var entry:GradientEntry;
                    for (var i:uint = 0; i < borderColors.length; i++){
                        entry = new GradientEntry(borderColors[i],borderRatios[i]);
                        entries.push(entry);
                    }
                    borderGradient.entries = entries;
                }
                else {
                    border.includeInLayout = false;
                }
            }

            private function updateIconAndLabel():void {
                var icon:Object = getStyle("icon");
                var data:Object = null;
                if (hostComponent.hasOwnProperty("data"))
                    data = hostComponent["data"];
                if (data && data.hasOwnProperty("icon")){
                    icon = data.icon;
                }
                if (icon){
                    img.source = icon;
                }
                else {
                    img.includeInLayout = false;
                }

                if (hostComponent.label && hostComponent.label.length > 0) {
                    if (icon == null){
                        labelDisplay.setStyle("textAlign",TextAlign.CENTER);
                    }
                    else if (getStyle("iconPosition") == "right") {
                        labelDisplay.setStyle("textAlign",TextAlign.RIGHT);
                        content.swapElements(img,labelDisplay);
                    }
                    else {
                        labelDisplay.setStyle("textAlign",TextAlign.LEFT);
                    }
                }
                else {
                    labelDisplay.includeInLayout = false;
                }
                content.paddingLeft = getStyle("padding");
                content.paddingRight = getStyle("padding");
            }
        ]]>        
    </fx:Script>

    <!-- states -->
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
        <s:State name="upAndSelected" />
        <s:State name="overAndSelected" />
        <s:State name="downAndSelected" />
        <s:State name="disabledAndSelected" />
    </s:states>

    <s:Rect 
        id="border" left="0" right="0" top="0" bottom="0"
        topLeftRadiusX="0" bottomLeftRadiusX="0" topRightRadiusX="0" bottomRightRadiusX="0">
        <s:fill>
            <s:LinearGradient id="borderGradient" rotation="90"/>
        </s:fill>
    </s:Rect>

    <s:Rect id="fill" left="1" right="1" top="1" bottom="1" 
            topLeftRadiusX="0" bottomLeftRadiusX="0" topRightRadiusX="0" bottomRightRadiusX="0">
        <s:fill>
            <s:LinearGradient rotation="90" id="fillGradient"/>
        </s:fill>
    </s:Rect>

    <s:HGroup id="content" gap="3" paddingLeft="4" paddingRight="4" paddingTop="2" paddingBottom="2" left="0" right="0"
              verticalCenter="0" verticalCenter.down="1" verticalAlign="middle" horizontalCenter="0" horizontalAlign="center">
        <s:BitmapImage id="img" verticalCenter="0"/>
        <s:Label id="labelDisplay" width="100%" verticalAlign="middle" maxDisplayedLines="1" paddingTop="1"/>
    </s:HGroup>

</s:SparkSkin>

这是我的自定义按钮类:

package  {
    import spark.components.Button;

    [Style(name="icon",type="*")]
    //Corner styles
    [Style(name="topLeftRadius",type="Number")]
    [Style(name="bottomLeftRadius",type="Number")]
    [Style(name="topRightRadius",type="Number")]
    [Style(name="bottomRightRadius",type="Number")]
    //Colors
    [Style(name="fillColors",type="Array",format="Color")]
    [Style(name="fillRatios",type="Array")]
    [Style(name="borderColors",type="Array",format="Color")]
    [Style(name="borderRatios",type="Array")]

    [Style(name="hasShadow",type="Boolean")]
    [Style(name="innerGlowColor",type="Number",format="Color")]
    [Style(name="hasInnerGlow",type="Boolean")]
    [Style(name="labelShadowColor",type="Number",format="Color")]
    [Style(name="hasLabelShadow",type="Boolean")]

    [Style(name="iconPosition", type="String", enumeration="left,right")]
    [Style(name="padding", type="Number")]
    public class CustomButton extends Button {
        public function CustomButton() {
            super();
        }
    }
}

使用flex sdk 4.1,一切正常,但是当使用flex 4.5.1鼠标光标越过按钮边框并导致按钮闪烁时,会多次触发mouse_over事件。

我无法弄清楚sdk中的哪些变化会导致此问题。 请帮我摆脱这种眨眼。

1 个答案:

答案 0 :(得分:0)

对于你的皮肤,尝试扩展 SparkButtonSkin 类而不是 SparkSkin

我建议你使用 iconDisplay 皮肤部分代替 img ,除非它正在用于其他目的。

注意:还要注意SparkButtonSkin的 autoIconManagement 属性,如果您在皮肤中手动管理iconDisplay的定位。