Actionscript 3 什么';设计自定义按钮的最佳方法是什么?选择此按钮后,可更改字体颜色/大小?

Actionscript 3 什么';设计自定义按钮的最佳方法是什么?选择此按钮后,可更改字体颜色/大小?,actionscript-3,button,Actionscript 3,Button,我想设计一个自定义组件来扩展按钮,它将有两种新样式:selectedColor和selectedFontSize。选择按钮时,这些选项将允许按钮具有不同的文本标签颜色和字体大小。(当我说“选中”时,我指的是选中状态,而不是被选中(鼠标按下) 我采用的方法是扩展按钮,添加两种新样式,然后覆盖选定的设置器,然后在原始颜色样式上使用setStyle将字体颜色更改为selectedColor(如果选择了按钮)或color(如果取消选择按钮) 在本例中,为了简单起见,我使用selectedColor,但我

我想设计一个自定义组件来扩展按钮,它将有两种新样式:selectedColor和selectedFontSize。选择按钮时,这些选项将允许按钮具有不同的文本标签颜色和字体大小。(当我说“选中”时,我指的是选中状态,而不是被选中(鼠标按下)

我采用的方法是扩展按钮,添加两种新样式,然后覆盖
选定的设置器,然后在原始颜色样式上使用setStyle将字体颜色更改为selectedColor(如果选择了按钮)或color(如果取消选择按钮)

在本例中,为了简单起见,我使用selectedColor,但我也希望能够为selectedFontSize做到这一点

[Style(name="selectedColor",type="uint", format="Color", inherit="no")]
[Style(name="selectedFontSize",type="Number",inherit="no")]

private var _deselectedColor:uint;
private var _selectedColor:uint;

override public function set selected(value:Boolean):void {
    super.selected = value;

    _selectedColor = getStyle("selectedColor") as uint;
    if (!_deselectedColor)
        _deselectedColor = getStyle("color") as uint;

    if (selected)
        setStyle("color",_selectedColor);
    else
        setStyle("color",_deselectedColor);
}
我正在存储原始颜色(即取消选择的颜色),因为当我
设置样式(“颜色”,取消选择的颜色)
时,它会被覆盖。我需要有一些方法在取消选择按钮时检索它

这种方法有很多问题。首先,在对象构造期间,第一次调用选定的setter时,样式尚未填充。因此,我得到的
color
为0x000000,而
selectedColor
为0x000000。一旦我在构造后手动更改按钮状态,样式就可以被读取没错,但现在已经太迟了,我已经存储了错误的值。此外,我需要能够在通过mxml、actionscript setStyle方法或css(静态和动态)进行设置时获得样式更新。这种方法显然不能做到这一点

我还尝试过重写
setStyle
styleChanged
方法。
setStyle
在通过mxml初始化按钮时,在构造过程中从未调用过,因此这是不可能的。
styleChanged
会被调用,但使用null作为styleProp,而不是我需要的颜色


专业人士是如何做到这一点的?

我想我现在对这个问题有了一个更加完美的答案

我最终在updateDisplayList()中完成了这项工作因此,更新将延迟到正式更新周期,而不是在执行选定的setter时强制更新。为了确保我没有存储错误的取消选择的颜色值,我现在只在选择按钮时存储它,并在取消选择按钮时清除存储

正如Amarghosh所建议的,我还使用CSSStyleDeclaration类来管理从css和mxml中读取自定义样式

最后,我发现一件大事是我需要调用super.callLater(invalidateDisplayList),否则按钮只会在我滚动时更新

完整的解决方案已经发布。希望这能帮助其他刚刚钻研自定义组件世界的人

import flash.display.Graphics;
import flash.geom.Matrix;

import mx.controls.Button;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;

[Style(name="selectedColor",type="uint", format="Color", inherit="no")]
[Style(name="selectedFontSize",type="Number",inherit="no")]

public class ControlBarButton extends Button
{
    private static var classConstructed:Boolean = constructStyle(); // initialize default style properties

    public function ControlBarButton() {
        super();
    }

    private static function constructStyle():Boolean {
        var style:CSSStyleDeclaration = StyleManager.getStyleDeclaration( "ControlBarButton" );

        // check to see if there's already an existing style declaration for this class
        if (style) {
            // its possible for a style to exist without defining all of the possible styles 
            // in which case we need to check each style explicitly and set a default if needed
            if ( style.getStyle( "selectedColor" ) == undefined ) {
                style.setStyle( "selectedColor", 0xFFFFFF );
            }
            if ( style.getStyle( "selectedFontSize" ) == undefined ) {
                style.setStyle( "selectedFontSize", 12 );
            }
        }
        else { // create a default style declaration
            style = new CSSStyleDeclaration();
            style.defaultFactory = function():void {
                this.selectedColor = 0xFFFFFF;
                this.selectedFontSize = 12;
            }
            StyleManager.setStyleDeclaration( "ControlBarButton", style, true );
        }

        return true;
    }

    private var selectedColorChanged:Boolean = true;
    private var selectedFontSizeChanged:Boolean = true;
    private var selectedChanged:Boolean = true;

    override public function styleChanged(styleProp:String):void {
        super.styleChanged(styleProp);

        // Check to see if style changed. 
        if (styleProp=="selectedColor") {
            selectedColorChanged=true;
            invalidateDisplayList();
            return;
        }
        if (styleProp=="selectedFontSize") {
            selectedFontSizeChanged=true;
            invalidateDisplayList();
            return;
        }
    }

    private var deselectedColorStored:Boolean = false;
    private var deselectedColorVal:uint;
    private var selectedColorVal:uint;
    private var deselectedFontSizeStored:Boolean = false;
    private var deselectedFontSizeVal:Number;
    private var selectedFontSizeVal:Number;

    override public function set selected(value:Boolean):void {
        super.selected = value;

        selectedChanged=true;
        invalidateDisplayList();
    }

    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        // selected color
        if (selectedColorChanged || selectedChanged) {
            if (selected) {
                if (!deselectedColorStored) {
                    deselectedColorVal = getStyle("color") as uint;
                    deselectedColorStored = true;
                }
                selectedColorVal = getStyle("selectedColor") as uint;
                setStyle("color",selectedColorVal);
                super.callLater(invalidateDisplayList);
            }
            else {
                if (deselectedColorStored) {
                    setStyle("color",deselectedColorVal);
                    super.callLater(invalidateDisplayList);
                    deselectedColorStored = false;
                }
            }

            selectedColorChanged=false;
        }

        // selected font size
        if (selectedFontSizeChanged || selectedChanged) {
            if (selected) {
                if (!deselectedFontSizeStored) {
                    deselectedFontSizeVal = getStyle("fontSize") as Number;
                    deselectedFontSizeStored = true;
                }
                selectedFontSizeVal = getStyle("selectedFontSize") as Number;
                setStyle("fontSize",selectedFontSizeVal);
                super.callLater(invalidateDisplayList);
            }
            else {
                if (deselectedFontSizeStored) {
                    setStyle("fontSize",deselectedFontSizeVal);
                    super.callLater(invalidateDisplayList);
                    deselectedFontSizeStored = false;
                }
            }

            selectedFontSizeChanged=false;
        }

        selectedChanged=false;
    }
}
你看到这个了吗